A:http://codeforces.com/contest/1400/problem/A
解析:
发现每一个字符串,都包含s[n-1],所以直接打印n个s[n-1]即可
#include<bits/stdc++.h> #include<map> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=1e5+10; const int maxn2=1e9+10; int answ[maxn]; int md[maxn]; int b[maxn]; int n,m; int a[maxn]; int v[maxn]; struct node { int x1,y1,x2,y2; }st[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; string s; cin>>s; for(int i=1;i<=n;i++) cout<<s[n-1]; cout<<endl; } }
B:http://codeforces.com/contest/1400/problem/B
题意:
两个袋子大小:p,f
两种物品数量:c1,c2
两种物品所占空间:s,w
求能装的最大数量
解析:
贪心来讲,规定s<w,那么对于第一个袋子,尽量先放s,然后w,第二个袋子也是如此
根据这个贪心思路,可以对第一个袋子拿取的s数量进行枚举,s装好,再装w。c1,c2去掉之前的消耗,再对第二个袋子进行同样操作。
细节在注释里
#include<bits/stdc++.h> #include<map> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=1e5+10; const int maxn2=1e9+10; struct node { int x1,y1,x2,y2; }st[maxn]; int main() { int t; cin>>t; while(t--) { ll p,f; ll c1,c2,s,w; cin>>p>>f>>c1>>c2>>s>>w; ll maxx=0; //这里并没有交换s,w,第一个袋子虽然应该优先装小的,但是下面的for已经枚举到了第一种袋子的所有可能 for(int i=0;i<=min(c1,p/s);i++) { ll s1,s2,s3;//i,s1为第一个袋子分别装s,w的数量。s2,s3分别为第二个袋子装s,w的数量 s1=(p-s*i); s1=min(s1/w,c2); if(s<=w) //第二个袋子优先选小 { if(f>=(c1-i)*s) //还能再装s { s2=c1-i; s3=min(c2-s1,(f-(c1-i)*s)/w); } else { s2=f/s; s3=0; } } else { if(f>=(c2-s1)*w)//还能再装w { s2=c2-s1; s3=min(c1-i,(f-(c2-s1)*w)/s); } else { s2=0; s3=f/w; } } maxx=max(maxx,i+s1+s2+s3); } cout<<maxx<<endl; } }
C:http://codeforces.com/contest/1400/problem/C
题意:
给出字符串s和整数x,求字符串w
s满足:
w[i+x]或w[i-x]为1,si为1,否则si为0
解析:
初始化w全为1。
遍历si的‘0‘,把w[i]变成符合对应要求
再次遍历si的‘1‘,如果w[i+x]==0&&w[i-x]==0,输出-1
#include<bits/stdc++.h> #include<map> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=1e5+10; const int maxn2=1e9+10; char s1[maxn],s2[maxn]; struct node { int x1,y1,x2,y2; }st[maxn]; int main() { int t; cin>>t; while(t--) { int x; cin>>s1>>x; int le=strlen(s1); for(int i=0;i<le;i++) s2[i]=‘1‘; for(int i=0;i<le;i++) { if(s1[i]==‘0‘) { if(i>=x) s2[i-x]=‘0‘; if(i+x<le) s2[i+x]=‘0‘; } } int ok = 0; for(int i=0;i<le;i++) { int ok1=0,ok2=0; if(s1[i]==‘1‘) { if(i>=x&&s2[i-x]==‘1‘) ok1=1; if(i+x<le&&s2[i+x]==‘1‘) ok2=1; if(!ok1&&!ok2) { ok=1;break; } } } if(ok) cout<<"-1"<<endl; else { for(int i=0;i<le;i++) cout<<s2[i]; cout<<endl; } } }
D:http://codeforces.com/contest/1400/problem/D
题意:
数组ai,1<=i<j<k<l<=n,求ai=ak,aj=al的数量
解析:
枚举j,l。
假设aj==al
....aj....ax.....al,要想凑够满足题意的那四个,需要aj之前存在与ax相等的数,有几个,就能和aj,al凑成几个。所以就需要记录aj之前出现了几个ax
cnt[]记录aj之前的各个数字出现的次数。
要注意一下顺序问题,cnt[]是要在for的最后更新才行。
#include<bits/stdc++.h> #include<map> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=3e3+10; const int maxn2=1e9+10; char s1[maxn],s2[maxn]; int a[maxn]; ll cnt[maxn]; struct node { int x1,y1,x2,y2; }st[maxn]; int main() { int t; cin>>t; while(t--) { memset(cnt,0,sizeof(cnt)); int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; ll sum = 0 ; for(int j=1;j<n;j++) { int md=0; for(int l=j+1;l<=n;l++) { if(a[j]==a[l]) sum+=md; md+=cnt[a[l]]; } cnt[a[j]]++; } cout<<sum<<endl; } }
E:http://codeforces.com/contest/1400/problem/E
题意:
给出数组
操作1:[L,R]集体减1
操作2:对任意一个数,把它变成比它自己小的任意一个数
把所有数归0的最小操作数
解析:
分治
之前做过。
[L,R]都变0的话,需要r-l+1步,
与集体减1那个操作取个min就可以了
#include<bits/stdc++.h> #include<map> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=5e3+10; const int maxn2=1e9+10; const int mod=1e9+10; char s1[maxn],s2[maxn]; ll a[maxn]; ll cnt[maxn]; struct node { int x1,y1,x2,y2; }st[maxn]; int ac(int l,int r) { if(l>r) return 0; int minn=mod; int k; for(int i=l;i<=r;i++) { if(a[i]<minn) { minn=a[i]; k=i; } } int md=a[k]; for(int i=l;i<=r;i++) a[i]-=minn; return min(r-l+1,md+ac(l,k-1)+ac(k+1,r)); } int sum=0; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; cout<<ac(1,n)<<endl; // cout<<sum<<endl; }
Educational Codeforces Round 94 (Rated for Div. 2)(A->E(分治))
原文:https://www.cnblogs.com/liyexin/p/13572992.html