CodeForces Round # 526(div 2)
题意:问电梯放在那一层的花费最小。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; int a[N]; int main(){ int ans = inf; int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); for(int i = 1; i <= n; ++i){ int tmp = 0; for(int j = 1; j <= n; ++j){ tmp += a[j] * 2 * (abs(i-j)+abs(j-1)+abs(1-i)); } ans = min(ans, tmp); } cout << ans << endl; return 0; }
题意:有n桶水, 问一共需要拿走k滴水,要求拿走之后n桶水最小的那个最大。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; LL a[N]; int main(){ int n; LL s; scanf("%d%lld", &n, &s); for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]); sort(a+1, a+1+n); LL tmp = 0; for(int i = 2; i <= n; ++i){ tmp += a[i] - a[1]; } LL need = s - tmp; if(need <= 0){ printf("%lld\n", a[1]); } else { need = (need + n-1) /n; a[1] -= need; if(a[1] < 0) puts("-1"); else printf("%lld\n", a[1]); } return 0; }
题解:
定义 ok 为 后面加了'a' 之后的合法序列数目, _ok为 后面加了 'b'之后可以变成ok的序列数目。
那么 每次遇到一个'a'就可以 ans += ok, _ok += ok,
然后遇到一个'b'就可以使得 ok += _ok, _ok = 0;
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; char s[N]; LL ans = 0, ok = 0, _ok = 0; int main(){ scanf("%s", s+1); int n = strlen(s+1); for(int i = 1; i <= n; ++i){ if(s[i] == 'a'){ ans += ok + 1; ans %= mod; _ok += ok + 1; _ok %= mod; } if(s[i] == 'b'){ ok += _ok; _ok = 0; ok %= mod; } } cout << ans << endl; return 0; }
D:The Fair Nut and the Best Path
题意:问在这[s,t]的串中选k个串,不同前缀的数目最大是多少。
题解:
定义 ok 为 第i位的不同前缀和的数目。
那么当i->i+1的时候, 如果我们不考虑 s, t的限制的话
ok -> ok * 2
限制又有了st的限制,如果 s[i+1] == 'b' 那么就说明 可以选择的方案数--, t[i+1] == 'a', 可以选择的方案数--,
注意不要爆LL就好了。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 5e5 + 100; char s[N], t[N]; int main(){ LL n, k; LL ans = 0, ok = 1; scanf("%lld%lld", &n, &k); scanf("%s%s", s, t); for(int i = 0; i < n; ++i){ ok = ok * 2; if(s[i] == 'b') ok--; if(t[i] == 'a') ok--; if(ok > mod) ok = mod; ans += min(ok, k); } cout << ans << endl; return 0; }
F:Max Mex