Codeforces Round #687 Div. 2 题解
吐了,比赛开始时。报名报成小号了。这次的 比较简单,没有码量题,好评。
A
分析
读懂题意,模拟即可。
代码
// sto xzc orz #include<bits/stdc++.h> using namespace std; #define pii pair<int,int> #define ll long long int read() { int x = 0,f = 0;char ch = getchar(); while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();} return f ? -x : x; } int main() { int T = read(); while(T--) { int a = read(),b = read(),c = read(),d = read(); int A = abs(a - c) + abs(b - d); int B = abs(a - c) + abs(d - 1); int C = abs(c - 1) + abs(b - d); int D = abs(c - 1) + abs(d - 1); printf("%d\n",max(max(A,B),max(C,D))); } }
B
分析
颜色数目比较少,直接枚举颜色种类,贪心选取。最后取最小值。
代码
#include<bits/stdc++.h> using namespace std; #define pii pair<int,int> #define ll long long int read() { int x = 0,f = 0;char ch = getchar(); while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();} return f ? -x : x; } const int N = 1e5 + 100,inf = 0x3f3f3f3f; int col[N],n,k,b[N]; bool vis[110]; vector<int> C; int main() { int T = read(); while(T--) { memset(vis,0,sizeof(vis));C.clear(); n = read();k = read(); for(int i = 1;i <= n;i++) { col[i] = read(); if(vis[col[i]] == 0) C.push_back(col[i]),vis[col[i]] = 1; } int ans = inf; for(auto p : C) { memcpy(b,col,sizeof(b));int sum = 0; for(int i = 1;i <= n;i++) { if(b[i] != p) { sum++;i = i + k - 1; } } ans = min(ans,sum); } printf("%d\n",ans); } }
C
分析
枚举删除多少个靠在前面的木板。枚举余数,从后到前枚举。
代码
// sto xzc orz #include<bits/stdc++.h> using namespace std; #define pii pair<int,int> #define ll long long ll read() { ll x = 0,f = 0;char ch = getchar(); while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();} return f ? -x : x; } const ll N = 6e5 + 100,inf = 1e18; ll a[N],b[N],A,B,n,ans,x,y,Tim = 0,cnt[N],dfn[N]; char ch[N]; signed main() { ll T = read(); while(T--) { n = read();A = read();B = read();ans = inf; scanf("%s" ,ch+1);Tim++; x = read();y = read(); for(int i = n;i >= A;i--) { ll now = (n - i) % B; if(dfn[now] != Tim) cnt[now] = 0,dfn[now] = Tim; cnt[now] += (ch[i]=='0'); ans = min(ans,cnt[now] * x + (i - A) * y); } printf("%lld\n", ans); } return 0; }
D
分析
比较好的一道题,个人感觉比 好。我们先分析如果有三个连续的数最高位相同,那么我们只需要对 个操作一次就好了,所以根据鸽巢原理。 时,可以直接输出 。那么当 时,我们仍有一个性质,我们操作的元素一定是一堆连续的元素,而且中间只会有一个断点。那么这个可以用异或前缀和维护。
代码
// sto xzc orz #include<bits/stdc++.h> using namespace std; #define pii pair<int,int> #define ll long long int read() { int x = 0,f = 0;char ch = getchar(); while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();} return f ? -x : x; } const int N = 1e5 + 100; int a[N],b[N],ans = 0x3f3f3f3f,n; int main() { n = read(); if(n >= 62) printf("1\n"); else { for(int i = 1;i <= n;i++) a[i] = read(); for(int i = 1;i <= n;i++) b[i] = a[i] ^ b[i - 1]; for(int i = 1;i <= n;i++) { for(int j = 0;j < i;j++) { for(int k = i + 1;k <= n;k++) { if((b[i] ^ b[j]) > (b[k] ^ b[i])) { ans = min(ans,k - j - 2); } } } } if(ans != 0x3f3f3f3f) cout << ans << endl; else cout << "-1" << endl; } }
E
分析
我们可以贪心的选取,每次选取最大的元素来做。我们先把所有元素分成 组,那么我们每次取出最大的一组,加上贡献。用 维护一下就好了。
代码
#include<bits/stdc++.h> using namespace std; #define pii pair<int,int> #define ll long long int read() { int x = 0,f = 0;char ch = getchar(); while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();} return f ? -x : x; } const int N = 5e5 + 100; multiset<ll> s; ll ans = 0; ll n,a[N],k; int main() { n = read();k = read(); for(ll i = 1;i <= k + 1;i++) s.insert(0); for(ll i = 1;i <= n;i++) a[i] = read(); sort(a + 1,a + 1 + n); for(ll i = n;i >= 1;i--) { ll x = *s.rbegin();s.erase(--s.end()); ans += x;s.insert(x + a[i]); }cout << ans << endl; return 0; }