https://codeforces.com/contest/538
A.Cutting Banner
题意给出一个字符串,你可以删除一段,看能不能拼成codeforces
#include<bits/stdc++.h> using namespace std; int main(){ string s; cin>>s; int fg=0; int len=s.size(); for (int i = 0; i < len; i++) { for (int j = i+1; j <= len; j++) { string pref = s.substr(0, i); string suf = s.substr(j); if (pref + suf == "CODEFORCES") { printf("YES "); return 0; } } } printf("NO "); }
B. Quasi Binary
给出一个整数,将其拆分成最小的quasibinary数(定义只含0,1的数 例如:10,11,100,101,111)
思路:从高位开始拆分,依次往下
#include<bits/stdc++.h> using namespace std; vector<int> v[11]; bool vis[11]; int a[11]; int cnt; int main(){ int n; cin>>n; while(n){ a[++cnt]=n%10; n/=10; } int ans=0; for(int i=cnt;i>=1;i--){ for(int k=1;k<=10;k++){ if(a[i]!=0){ v[k].push_back(1); if(!vis[k]){ ans++; vis[k]=1; } a[i]--; }else { if(v[k].size()!=0) { if(!vis[k]){ ans++; vis[k]=1; } v[k].push_back(0); } } } } cout<<ans<<endl; for(int i=1;i<=9;i++){ int fg=0; for(auto x:v[i]){ cout<<x; fg=1; } if(fg) cout<<" "; } }
C. Tourist's Notes
一共n天,以及第mi天的高度,保证任意两天的高度距离相差<=1 求最高的高度
思路:贪心,能从已知的相邻的两天的高度,求出一个山型的最高距离即可 然后处理第一天和最后一天
#include<bits/stdc++.h> using namespace std; struct node{ int t,h; }p[100005]; int main(){ int n,k; cin>>n>>k; for(int i=1;i<=k;i++) cin>>p[i].t>>p[i].h; //sort(p+1,p+1+k); int Max=0; for(int i=1;i<=k;i++){ if(i==1){ Max=p[i].h+p[i].t-1; }else { if(abs(p[i].h-p[i-1].h)>p[i].t-p[i-1].t){ return 0*puts("IMPOSSIBLE"); }else { int pos=p[i].t-p[i-1].t; int a=p[i].h; int b=p[i-1].h; int z=abs(a-b); int ha=pos-z; Max=max(Max,max(a,b)+ha/2); } } } Max=max(Max,p[k].h+n-p[k].t); cout<<Max<<" "; return 0; }
D.Weird Chess
给出一个矩阵,o代表棋子,x代表可攻击到的范围,.代表攻击不到的。我们需打印个(2n-1)*(2n-1)的矩阵即可
思路:我们把不能‘.'号全部输出到矩阵上然后判断'x'是否会与'.'重叠,重叠则输出no
#include<bits/stdc++.h> using namespace std; char s[105][105]; bool vis1[105][105]; bool vis2[105][105]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) scanf("%s",s[i]+1); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(s[i][j]=='o'){ for(int k=1;k<=n;k++){ for(int z=1;z<=n;z++){ if(s[k][z]=='.'){ vis1[n+k-i][n+z-j]=1;//把'.' } } } } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(s[i][j]=='o'){ for(int k=1;k<=n;k++){ for(int z=1;z<=n;z++){ if(s[k][z]=='x'&&!vis1[n+k-i][n+z-j]){ vis2[k][z]=1; }//判断是否能攻击到 '.' 的位置 } } } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(s[i][j]=='x'){ if(vis2[i][j]!=1){ return 0*puts("NO"); } } } } puts("YES");//如果所有'x'都合法 for(int i=1;i<=n*2-1;i++,puts("")){ for(int j=1;j<=n*2-1;j++){ if(i==n&&j==n) cout<<"o"; else if(vis1[i][j]) cout<<"."; else cout<<"x"; } } return 0; }
E. Demiurges Play Again
树形博弈 待学
F. A Heap of Heaps
构造一个k叉堆,需使得子节点都发育根节点,否则此点算违法点,输出违法点个数
对某个节点造成贡献的儿子节点的值一定小于该节点。
把节点按值排序,从小到大枚举每个节点。对于k叉堆,它儿子中被处理过的节点数,就是这个点对答案中k叉堆情况的贡献。
然后我们用树状数组维护一段连续区间小于根节点的值即可
#include<bits/stdc++.h> #define LL long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn = 200005; int n; int ans[maxn]; int tree[maxn]; struct node{ int val; int id; bool friend operator < (const node u,const node v){ if(u.val==v.val) return u.id<v.id; return u.val<v.val; } }p[maxn]; int lowbit(int k){ return k&(-k); } void add(int x){ if(x==0) return; while(x<n){ tree[x]+=1; x+=lowbit(x); } } int get_sum(int x){ int ans=0; while(x){ ans+=tree[x]; x-=lowbit(x); } return ans; } void solve(){ for(int i=0;i<n;i++){ int id=p[i].id; for(int k=1;k<n&&k*id+1<n;k++){ ans[k]+=get_sum(min(n-1,k*id+k))-get_sum(k*id);//以p[i]为根节点 算贡献 } add(p[i].id); } for(int i=1;i<=n-1;i++){ cout<<ans[i]<<" "; } } int main(){ cin>>n; for(int i=0;i<n;i++){ cin>>p[i].val; p[i].id=i; } sort(p,p+n); solve(); }