比賽地址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"); }