Educational Codeforces Round 103 (Rated for Div. 2)爆炸记
A
这题WA了2次,出师不利。n>k的情况很特殊,若n%k==0答案是1,否则是2,n<=k时,答案是k/n上取整
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int main() { int T,n,k,rest;scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); if(n%k==0)puts("1"); else if(n>k)puts("2"); else printf("%d\n",(k-1)/n+1); } }
B
容易发现修改数据只需加在第一个数就行,然后循环枚举一遍x/sum<=k/100,移项得sum>=100x/k,每个位置找最大值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int T,n,k; long long ans,s,x; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); s=ans=0; for(int i=1;i<=n;i++) { scanf("%lld",&x); if(i>1)ans=max(ans,(100*x-1)/k+1-s); s+=x; } printf("%lld\n",ans); } }
C
从后往前模拟,若出现首尾连接在一起则直接统计答案,重新开始计算,否则可以手算出带上当前位置后答案的改变,若小于链长则替换为链长
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; int T,n,c[N],a[N],b[N]; long long ans,sum; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)scanf("%d",&b[i]); ans=0,sum=c[n]-1; for(int i=n;i>1;i--) if(a[i]==b[i])ans=max(ans,sum+2),sum=c[i-1]-1; else{ int u=min(a[i],b[i]),v=max(a[i],b[i]); ans=max(ans,sum+2+v-u); sum=max(sum+1+c[i-1]-v+u,c[i-1]-1ll); } printf("%lld\n",ans); } }
D
裸DP,l/r[i][0/1]表示变换了0/1次后向左/右最长能走多少距离,直接推状态即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N=3e5+7; int n,l[N][2],r[N][2]; char a[N]; int main() { int T;scanf("%d",&T); while(T--) { scanf("%d",&n); scanf("%s",a+1); l[0][0]=l[0][1]=0; for(int i=1;i<=n;i++) { if(a[i]=='L')l[i][1]=0,l[i][0]=l[i-1][1]+1; else l[i][0]=0,l[i][1]=l[i-1][0]+1; } r[n][0]=r[n][1]=0; for(int i=n-1;~i;i--) { if(a[i+1]=='R')r[i][1]=0,r[i][0]=r[i+1][1]+1; else r[i][0]=0,r[i][1]=r[i+1][0]+1; } for(int i=0;i<=n;i++)printf("%d ",l[i][0]+r[i][0]+1); puts(""); } }
E
555看错题了,实际上很水,对每个串枚举变为_的位置然后建边,此时就排除掉一些不符合的情况,然后就是裸的拓扑排序了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+7; int n,m,d,mt,cnt,sid[150],ans[N],deg[N]; string t,s[N]; map<int,int>pos; vector<int>G[N]; int calc(string s) { int ret=0; for(int i=0;i<s.size();i++)ret=ret*28+sid[s[i]]; return ret; } int main() { for(int i=0;i<26;i++)sid[i+'a']=i;sid['_']=27; cin>>n>>m>>d; for(int i=1;i<=n;i++)cin>>s[i]; for(int i=1;i<=n;i++)pos[calc(s[i])]=i; for(int i=1;i<=m;i++) { cin>>t;scanf("%d",&mt); bool has=0; for(int S=0;S<(1<<d);S++) { string tt=t; for(int j=0;j<t.size();j++)if((S>>j)&1)tt[j]='_'; int val=calc(tt); if(pos.find(val)!=pos.end()) { if(pos[val]==mt)has=1; else G[mt].push_back(pos[val]),deg[pos[val]]++; } } if(!has){puts("NO");return 0;} } queue<int>q; for(int i=1;i<=n;i++)if(!deg[i])q.push(i); while(q.size()) { int u=q.front();q.pop(); ans[++cnt]=u; for(int i=0;i<G[u].size();i++)if(!(--deg[G[u][i]]))q.push(G[u][i]); } if(cnt<n)puts("NO"); else{ puts("YES"); for(int i=1;i<=n;i++)printf("%d ",ans[i]); } }
WA了2发A+看错E题目=排名很烂,rank=249 rating+=160