标签:efi gif break pen span amp 转换 char click
C:模拟:未跳到目的地之前先贪心放板子,能到达目的地后紧贴着放板子
先判能不能跳到目的地,能跳到再考虑是否需要将后面的板子往前移动
#include<bits/stdc++.h> using namespace std; #define N 20005 int sum,n,m,d,c[N],ans[N],ans1[N]; int main(){ cin>>n>>m>>d; for(int i=1;i<=m;i++)cin>>c[i],sum+=c[i]; if(sum>n){puts("NO");return 0;} int pos=0,id,R=0; for(id=1;id<=m;id++){ if(pos+d>=n+1){//直接贴着放板子即可 for(int i=R+1;i<=R+c[id];i++) ans[i]=id; R+=c[id]; } else {//贪心放板子 pos+=d;//跳到pos+d去 for(int i=pos;i<=pos+c[id]-1;i++) ans[i]=id; pos+=c[id]-1; R=pos; } } if(pos+d<n+1){puts("NO");return 0;} if(pos+d>=n+1 && R<=n){ puts("YES"); for(int i=1;i<=n;i++) cout<<ans[i]<<" "; return 0; } int ind=n; for(int i=R;i>=1;i--){ ind=min(ind,i); if(ans[i]){ ans1[ind]=ans[i]; ind--; } } puts("YES"); for(int i=1;i<=n;i++) cout<<ans1[i]<<" "; return 0; }
D:贪心往前移动0即可,注意k是long long
#include<bits/stdc++.h> using namespace std; #define N 1000006 #define ll long long long long n,k; char s[N]; int main(){ int q;cin>>q; while(q--){ scanf("%lld%lld",&n,&k); scanf("%s",s+1); ll tot=0,len=0; for(int i=1;i<=n;i++){ if(s[i]==‘1‘){ tot++; } else { if(tot<=k){ k-=tot; ++len; swap(s[i],s[len]); } else {//只能往前移动k格 swap(s[i],s[i-k]); break; } } } printf("%s\n",s+1); } }
E:贪心,肯定是分队伍越多越好,六个人的队显然没有两只三人队优
先排序,dp[i]表示取前i人的最优解,
枚举3<=j<=5,dp[i]=min(dp[i-j]+a[i]-a[i-j+1]);
#include<bits/stdc++.h> using namespace std; #define ll long long #define N 200005 struct Node{ ll id,a; }p[N]; ll n,ans[N],dp[N],pre[N]; int cmp(Node a,Node b){ return a.a<b.a; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>p[i].a; p[i].id=i; } sort(p+1,p+1+n,cmp); dp[3]=p[3].a-p[1].a; pre[3]=0; dp[4]=p[4].a-p[1].a; pre[4]=0; dp[5]=p[5].a-p[1].a; pre[5]=0; for(int i=6;i<=n;i++){ dp[i]=dp[i-3]+p[i].a-p[i-2].a; pre[i]=i-3; for(int j=4;j<=5;j++){ if(i-j<3)continue; if(dp[i]>dp[i-j]+p[i].a-p[i-j+1].a){ dp[i]=dp[i-j]+p[i].a-p[i-j+1].a; pre[i]=i-j; } } } cout<<dp[n]<<‘ ‘; int pos=n,now=0; while(pos){ ++now; int tmp=pre[pos]; for(int i=tmp+1;i<=pos;i++) ans[p[i].id]=now; pos=tmp; } cout<<now<<‘\n‘; for(int i=1;i<=n;i++)cout<<ans[i]<<‘ ‘; }
F:将一长段逆转转换成每次只逆转相邻两个字符,如果字符集不同,显然不行
字符集相同:分成两种情况:
1,某种字符出现>=2次,那么这种情况必然有解:先将这两个字符挨在一起,然后就可以随便搞了
2,每种字符出现1次,那么求出s转换成t的步数,偶数有解,奇数无解
#include<bits/stdc++.h> using namespace std; #define N 200005 char s[N],t[N]; int n,cnt1[100],cnt2[100],pos1[100],pos2[100]; int main(){ int T;cin>>T; while(T--){ for(int i=0;i<26;i++) cnt1[i]=cnt2[i]=pos1[i]=pos2[i]=0; cin>>n; cin>>s>>t; for(int i=0;i<n;i++) cnt1[s[i]-‘a‘]++,cnt2[t[i]-‘a‘]++; int flag=0; for(int i=0;i<26;i++) if(cnt1[i]!=cnt2[i]) flag=1; if(flag){puts("NO");continue;} flag=0; for(int i=0;i<26;i++) if(cnt1[i]>=2) flag=1; if(flag){puts("YES");continue;} int sum=0; for(int i=0;i<n;i++){ int pos=i; while(s[pos]!=t[i])pos++; for(int j=pos;j>i;j--){ swap(s[j],s[j-1]); sum++; } } if(sum%2==0)cout<<"YES\n"; else puts("NO"); } }
标签:efi gif break pen span amp 转换 char click
原文地址:https://www.cnblogs.com/zsben991126/p/11801393.html