退役一周年祭
A
没看清是任意顺序耽误了几分钟,首先最大值应该>=2个,若是3个则都为最大值,否则就两个次大值一个最大值

#include<bits/stdc++.h> using namespace std; int T,a[3]; int main() { cin>>T; while(T--) { cin>>a[0]>>a[1]>>a[2]; int mx=a[0],num=1; for(int i=1;i<=2;i++)if(a[i]>mx)mx=a[i],num=1;else if(a[i]==mx)num++; if(num==1)puts("NO"); else{ puts("YES"); if(num==3)printf("%d %d %d ",a[0],a[0],a[0]); else if(a[0]!=mx)printf("%d %d %d ",a[0],a[0],a[1]); else if(a[1]!=mx)printf("%d %d %d ",a[1],a[0],a[1]); else printf("%d %d %d ",a[0],a[2],a[2]); } } }
B
直接输出未出现过的即可

#include<bits/stdc++.h> using namespace std; int T,n,a[90]; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++)a[i]=0; for(int i=1,x;i<=2*n;i++) { scanf("%d",&x); if(!a[x])a[x]=1,printf("%d ",x); } puts(""); } }
C
从后往前,找最长的单峰序列

#include<bits/stdc++.h> using namespace std; int n,a[200500]; int main() { int T;scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); int p=n; while(p>1&&a[p-1]>=a[p])p--; while(p>1&&a[p-1]<=a[p])p--; printf("%d ",p-1); } }
D
区间DP,写法可以仿照线段树,复杂度O(n(logn+26))轻松通过

#include<bits/stdc++.h> using namespace std; const int N=131075; int n,num,a[N],lg[N],s[N][26]; char str[N]; int bushi(int l,int r,int now){return r-l+1-(s[r][now]-s[l-1][now]);} int dp(int l,int r,int now) { if(l==r)return a[l]!=now; int mid=l+r>>1,sl=dp(l,mid,now+1),sr=dp(mid+1,r,now+1); return min(sl+bushi(mid+1,r,now),sr+bushi(l,mid,now)); } int main() { lg[0]=1;for(int i=1;i<=16;i++)lg[1<<i]=i; int T;scanf("%d",&T); while(T--) { scanf("%d%s",&n,str+1); for(int i=1;i<=n;i++)a[i]=str[i]-'a'; for(int i=1;i<=n;i++)for(int j=0;j<26;j++)s[i][j]=s[i-1][j]+(a[i]==j); printf("%d ",dp(1,n,0)); } }
E
我弱智了,实际上直接topsort判环,然后可以得到一个拓扑序列,把边从拓扑序列靠前的连向靠后的就行了,原图无环一定能构造

#include<bits/stdc++.h> #define fi first #define se second using namespace std; typedef long long ll; const int N=2e5+7; int n,m,cnt,tot,deg[N],hd[N],v[N<<1],nxt[N<<1],pos[N],q[N]; vector<pair<int,int> >e; void add(int x,int y){v[++cnt]=y,nxt[cnt]=hd[x],hd[x]=cnt;} int main() { int T;scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); e.clear(),cnt=tot=0; for(int i=1;i<=n;i++)pos[i]=deg[i]=hd[i]=0; for(int i=1,t,x,y;i<=m;i++) { scanf("%d%d%d",&t,&x,&y); e.push_back(make_pair(x,y)); if(t==1)add(x,y),deg[y]++; } int qs=0,qe=0; for(int i=1;i<=n;i++)if(!deg[i])q[qe++]=i; while(qs<qe) { int u=q[qs++]; pos[u]=++tot; for(int i=hd[u];i;i=nxt[i])if(!(--deg[v[i]]))q[qe++]=v[i]; } if(tot!=n)puts("NO"); else{ puts("YES"); for(int i=0;i<e.size();i++) { if(pos[e[i].fi]>pos[e[i].se])swap(e[i].fi,e[i].se); printf("%d %d ",e[i].fi,e[i].se); } } } }
F
贪心。如果k是1,那么答案就是n-1。k>=2时用队列把叶子数大于k的叶子入队,取出队头的时候更新叶子数。

#include<bits/stdc++.h> using namespace std; const int N=2e5+100; int n,k,ans,qs,qe,lf[N],b[N],vis[N],q[N]; vector<int>G[N]; int main() { int T;scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)G[i].clear(),lf[i]=b[i]=vis[i]=0; for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x); if(k==1){printf("%d ",n-1);continue;} for(int i=1;i<=n;i++) { b[i]=G[i].size(); if(b[i]==1)lf[G[i][0]]++; } ans=qs=qe=0; for(int i=1;i<=n;i++)if(lf[i]>=k)vis[q[qe++]=i]=1; while(qs<qe) { int u=q[qs++]; ans++; lf[u]-=k,vis[u]=0,b[u]-=k; if(lf[u]>=k)vis[q[qe++]=u]=1; if(b[u]==1) { b[u]=0; for(int i=0;i<G[u].size();i++) if(b[G[u][i]]) { lf[G[u][i]]++; if(lf[G[u][i]]>=k&&!vis[G[u][i]])vis[q[qe++]=G[u][i]]=1; } } } printf("%d ",ans); } }
G
不会写咕了
rank272 新号rating=651,为啥CF新号从rating=0算起了?上分好慢啊(不过就你div3进不了前250还想上分?)