比赛地址c++
题目连接
⭐数组
题目:
给出\(a\),\(b\),\(c\),求出比\(c\)大的最近的\(a\)或\(b\)的倍数到\(c\)的距离spa
解析:
向上找最近倍数取最小值便可code
#include<bits/stdc++.h> using namespace std; /*===========================================*/ int main() { int T; LL p, a, b, c; scanf("%d", &T); while (T--) { scanf("%lld%lld%lld%lld", &p, &a, &b, &c); LL t[3] = { (p + a - 1) / a * a,(p + b - 1) / b * b ,(p + c - 1) / c * c }; printf("%lld\n", min({ t[0],t[1],t[2] }) - p); } }
题目连接
⭐排序
题目:
给出一叠牌,两个空位(一个有牌,一个没牌),每次能够取出一部分牌按顺序放在另外一堆上,若是要保证\(排序值\)最大,则要如何移动牌堆
排序值定义字符串
解析:
由排序值定义可知,越大的数排在越前面这个值越大,则每次寻找出剩余序列中最大的数,将此后的数放入另外一堆中,便可构成此序列get
#include<bits/stdc++.h> using namespace std; /*===========================================*/ const int maxn = 1e5 + 5; int dat[maxn]; bool vis[maxn]; int main() { int T, n; scanf("%d", &T); while (T--) { MEM(vis, 0); scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d", &dat[i]); int mx = n; int last = n; for (int i = n - 1; i >= 0; --i) { vis[dat[i]] = true; if (dat[i] == mx) { for (int j = i; j < last; ++j) printf("%d ", dat[j]); while (vis[mx]) --mx; last = i; } } printf("\n"); } }
题目连接
⭐⭐it
题目:
给出字符串\(s,t\),长度分别为\(n\),\(m\),一定存在\(p\)序列,知足\(1\le p_1<p_2<\dots<p_m\le n\),而且\(s_{p_i}=t_i\),求出拥有最大相邻元素间距的\(p\)序列ast
解析:
对于任意一个\(t\)中的字符能够映射到\(s\)中的一些字符,求出每一个字符可以映射的最小合法距离和最大合法距离,求出\(\max_{i=2}^m(high[i]-[low[i-1]])\)class
#include<bits/stdc++.h> using namespace std; /*===========================================*/ const int maxn = 2e5 + 5; char s[maxn], t[maxn]; int lens, lent; int low[maxn], high[maxn]; int main() { scanf("%d%d", &lens, &lent); scanf("%s%s", s + 1, t + 1); int p = 1; for (int i = 1; i <= lent; ++i, ++p) { if (s[p] != t[i]) ++p; low[i] = p; } p = lens; for (int i = lent; i > 0; --i, --p) { if (s[p] != t[i]) --p; high[i] = p; } int mx = 0; for (int i = 2; i <= lent; ++i) mx = max(mx, high[i] - low[i - 1]); printf("%d", mx); }
题目连接
⭐⭐⭐
题目:
存在两个二进制数,均有\(a\)个\(0\)和\(b\)个\(1\),且大的二进制数减去小的二进制数有\(k\)个\(1\),若这样的一对二进制数存在,求出对应的二进制数
解析:
假设下列讨论01表明同一位大数为0,小数为1;00表明同一位大数为0,小数为0...
对于00,11,10状况,在未出现借位时,贡献分别为0,0 ,1
对于01时 贡献为1,出现借位,对后序出现的4种状况进行讨论
能够看出每对01都须要一对10来终止,且能够确定的是01与10出现的次数相等,且花费了2个0和两个1只能贡献1,而若是这两个0两个1以00,11的形式出如今借位过程当中能够得到更多个1
因此这对二进制数必定是如下述方式存在的
#include<bits/stdc++.h> using std::min; /*===========================================*/ const int maxn = 2e5 + 5; char ret[2][maxn]; int index = 0; int main() { int a, b, c; scanf("%d%d%d", &a, &b, &c); int t = min(a, b); if (!c || c <= a + b - 2 && !a && b != 1) { if (c) { --a, --b, --c; while (a + b > c && b--) ret[0][index] = ret[1][index] = '1', ++index; ret[0][index] = '1'; ret[1][index++] = '0'; while (a-- && c--) ret[0][index] = ret[1][index] = '0', ++index; while (c-- > 0) ret[0][index] = ret[1][index] = '1', ++index; ret[0][index] = '0'; ret[1][index++] = '1'; while (~(a--)) ret[0][index] = ret[1][index] = '0', ++index; } else { for (int i = 0; i < b; ++i, ++index) ret[0][index] = ret[1][index] = '1'; for (int i = 0; i < a; ++i, ++index) ret[0][index] = ret[1][index] = '0'; } printf("%s\n%s", ret[0], ret[1]); } else printf("No"); }
题目连接
⭐⭐⭐⭐
题目:
给出\(n\)组关于某一个长度为\(m\)的数组的复制,每组种至多只有两处与原数组不一样,判断这样的原数组是否存在并输出
解析:
能够假定第一个数组就是原数组,朴素的去统计每组数据最多的不一样之处,进行分类讨论
能够分析第一个数组存在至多两处不一样,其余数组也至多存在两个不一样,因此第一个数组为假定的状况下与其余数组至多出现4处不一样
总结:
注意:
#include<bits/stdc++.h> using namespace std; /*===========================================*/ vector<vector<int> > dat; int n, m; vector<int> ret; int dif; int id; void cnt() { dif = 0; for (int i = 1; i < n; ++i) { int c = 0; for (int j = 0; j < m; ++j) if (ret[j] != dat[i][j]) ++c; if (c > dif) { dif = c; id = i; } } } void yes() { printf("Yes\n"); for_each(ret.begin(), ret.end(), [](int& i) {printf("%d ", i); }); exit(0); } int main() { scanf("%d%d", &n, &m); dat.assign(n, vector<int>(m)); for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) scanf("%d", &dat[i][j]); ret.assign(dat[0].begin(), dat[0].end()); cnt(); if (dif <= 2) yes(); else if (dif == 3) { int tmp = id; for (int i = 0; i < m; ++i) { if (dat[tmp][i] != ret[i]) { ret[i] = dat[tmp][i]; cnt(); int iid = id; if (dif <= 2) yes(); else if (dif == 3) { for (int j = 0; j < m; ++j) if (dat[iid][j] != ret[j]) { int t = ret[j]; ret[j] = dat[iid][j]; cnt(); if (dif <= 2) yes(); ret[j] = t; } } ret[i] = dat[0][i]; } } } else if (dif == 4) { int iid = id; int r[4], p = 0; for (int i = 0; i < m; ++i) if (dat[id][i] != ret[i]) r[p++] = i; for (int i = 1; i < 4; ++i) for (int j = 0; j < i; ++j) { ret[r[i]] = dat[iid][r[i]]; ret[r[j]] = dat[iid][r[j]]; cnt(); if (dif <= 2) yes(); ret[r[i]] = dat[0][r[i]]; ret[r[j]] = dat[0][r[j]]; } } printf("No"); }