比赛地址ios
题目连接
⭐c++
题目:
给出一个数组\(a\)并能进行一个操做使得数组元素更改成数组任意其余两元素之和,问是否可让数组元素所有小于等于\(d\)数组
解析:
排序后判断最大值是否小于等于\(d\)或者最小的两个值是否小于等于\(d\)便可优化
#include<bits/stdc++.h> using namespace std; const int maxn = 105; int n, dat[maxn]; int main() { int T; scanf("%d", &T); while (T--) { int n, d; dat[1] = 0; scanf("%d%d", &n, &d); for (int i = 0; i < n; ++i) scanf("%d", &dat[i]); sort(dat, dat + n); printf("%s\n", dat[n - 1] <= d || dat[0] + dat[1] <= d ? "YES" : "NO"); } }
题目连接
⭐spa
题目:
给出两个字符串,定义\(LCM(S_1,S_2)\)是由这两个串做为循环节的最小长度串,问\(LCM(S_1,S_2)\)是什么,若是不存在则输出\(-1\)code
解析:
若是\(LCM\)存在,则它的长度必定是\(LCM(len_1,len_2)\),那么已知最终串的长度,就能够算出每一个循环节的循环次数,判断循环倍增后的串是否相同便可排序
#include<bits/stdc++.h> using namespace std; string str[2]; string repeat(const string& a, int x) { string t; while (x--) t += a; return t; } int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while (T--) { cin >> str[0] >> str[1]; int d = gcd(str[0].length(), str[1].length()); string t[2] = { repeat(str[0],str[1].length() / d),repeat(str[1],str[0].length() / d) }; cout << (t[0] == t[1] ? t[0] : "-1") << endl; } }
题目连接
⭐⭐索引
题目:
给出\(n\)与\(k\),以及对应的数组\(a=1,2,\dots,k-1,k,k-1,k-2,\dots,k-(n-k)\),如今假定有一个长度为\(k\)的排列\(p\),依照他构造出数组\(b\),使得\(b[i]=p[a[i]]\),问使得\(b\)中逆序对数不超过\(a\)的话,p中知足要求的且为最大字典序的排列是什么ci
解析:
这样的变换能够理解为\(a\)为索引下表,\(b\)为对应值
o( ̄▽ ̄)ブ找规律能够发现,将本来\(k,k-1,k-2,\dots,k-(n-k)\)进行倒序排列,逆序对数不会改变,且可让字典序增长,但除此以外的序列仍然须要服从正序排列\(1\dots n-(n-k+1)\)字符串
#include<bits/stdc++.h> using namespace std; int n, k; int main() { int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &k); int a = n - k; int b = k - a; for (int i = 1; i < b; ++i) printf("%d ", i); for (int j = 0; j <= a; ++j) printf("%d ", k - j); printf("\n"); } }
题目连接
⭐⭐
题目:
给出一系列操做“+1”“-1”,以及\(q\)次查询,每次查询区间\([l,r]\)内的操做忽略,那么打印出整个操做序列中出现的不一样数值的个数
解析:
注:
这道题用\(st\)表,线段树也能够,可是更浪费时间,由于这道题只须要得到两端的极值,且对于求取后半段极值的方法,也不必定必须用\(dp\),也能够直接从后向前遍历找到加上以前操做的影响得到的极值,使用时减去影响便可(即\(eh[r+1]-sum[r]\)),两种求解都是\(O(n)\)处理
#include<bits/stdc++.h> using namespace std; const int maxn = 2e5 + 5; int sh[maxn], sl[maxn], sum[maxn], eh[maxn], el[maxn]; char op[maxn]; int main() { int t, n, m; scanf("%d", &t); while (t--) { scanf("%d%d%s", &n, &m, op + 1); for (int i = 1; i <= n; i++) { if (op[i] == '+') sum[i] = sum[i - 1] + 1; else sum[i] = sum[i - 1] - 1; sh[i] = max(sh[i - 1], sum[i]); sl[i] = min(sl[i - 1], sum[i]); } eh[n + 1] = el[n + 1] = 0; for (int i = n; i >= 1; i--) { if (op[i] == '+') { eh[i] = eh[i + 1] + 1; el[i] = el[i + 1] == 0 ? 0 : el[i + 1] + 1; } else { eh[i] = eh[i + 1] == 0 ? 0 : eh[i + 1] - 1; //也能够写做eh[i]=max(eh[i+1]-1,0) el[i] = el[i + 1] - 1; } } int l, r; while (m--) { scanf("%d%d", &l, &r); int low = min(sl[l - 1], sum[l - 1] + el[r + 1]), high = max(sh[l - 1], sum[l - 1] + eh[r + 1]); printf("%d\n", high - low + 1); } } return 0; }
题目连接
⭐⭐⭐⭐
题目:
给出一张图,定义\((u,v)\)的路径权值=路径权重之和+路径中最小的权重-路径中最大的权重,求\(1\)到各点的路径权值最小值
解析:
同时每一个转移方程能够类比dijkstra,使用堆优化,寻找当前最短路径,保证每次能够肯定一个最终状态
3. 最终答案输出状态3对应的值便可
注意:
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define MEM(X,Y) memset(X,Y,sizeof(X)) typedef long long LL; using namespace std; /*===========================================*/ const int maxn = 2e5 + 5; struct Edge { int to; LL w; }; struct Node { int st, p; LL w; }; queue<Node> q; vector<Edge> e[maxn]; LL dis[maxn][4]; void add(int u, int v, int w) { e[u].push_back(Edge{ v,w }); e[v].push_back(Edge{ u,w }); } void dij() { dis[1][0] = 0; q.push(Node{ 0,1,0 }); while (!q.empty()) { auto t = q.front(); q.pop(); if (dis[t.p][t.st] != t.w) continue; for (auto& i : e[t.p]) { if (dis[t.p][t.st] + i.w < dis[i.to][t.st]) { dis[i.to][t.st] = dis[t.p][t.st] + i.w; q.push(Node{ t.st,i.to ,dis[i.to][t.st] }); } if (!(t.st & 1) && dis[t.p][t.st] < dis[i.to][t.st | 1]) { dis[i.to][t.st | 1] = dis[t.p][t.st]; q.push(Node{ t.st | 1,i.to,dis[i.to][t.st | 1] }); } if (!(t.st & 2) && dis[t.p][t.st] + 2 * i.w < dis[i.to][t.st | 2]) { dis[i.to][t.st | 2] = dis[t.p][t.st] + 2 * i.w; q.push(Node{ t.st | 2,i.to,dis[i.to][t.st | 2] }); } } } } int main() { MEM(dis, INF); int n, m; int a, b, c; scanf("%d%d", &n, &m); while (m--) { scanf("%d%d%d", &a, &b, &c); add(a, b, c); if (a > b) swap(a, b); if (a == 1) dis[b][3] = c; } dij(); for (int i = 2; i <= n; ++i) printf("%lld ", dis[i][3]); }