CF Round#436 div2
额,这次的题目其实挺智障的。所以通过这次比赛,我也发现了自己是一个智障。。。。
不说太多,说多是泪。。。
A. Fair Game
题意:给你一个数组,看你能否把它均分为两个所有元素均相同的子数组。
模拟即可。。。。
#include<bits/stdc++.h> using namespace std; #define MAXN 100+10 int n,c[MAXN],a=0,b=0; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); c[x]++; if(!a)a=x; else if(x!=a)b=x; } if(c[a]==c[b]&&c[a]+c[b]==n)printf("YES\n%d %d",a,b); else printf("NO"); return 0; }
B. Polycarp and Letters
题意:给你一个字符串,请你找出一个满足如下要求的子序列:
1.子序列由不同的小写字母组成。
2.子序列中两个相邻的小写字母在原串的位置之间不得夹杂着大写字母
贪心地选就行了
#include<bits/stdc++.h> using namespace std; #define MAXN 210 int n,ans=0,cnt[29]; char s[MAXN]; bool judge(char c){return (c>='a'&&c<='z');} int main(){ scanf("%d",&n); scanf("%s",s); int len=0; for(int i=0;i<=n;i++){ if(i!=n&&judge(s[i])){ if(!cnt[s[i]-'a'])cnt[s[i]-'a']++,len++; } else{ans=max(ans,len);len=0;memset(cnt,0,sizeof(cnt));} } printf("%d",ans); return 0; }
C. Bus
题意:一趟巴士在a公里的直线上来回穿梭k次(来去各算一次),巴士的油箱容量为b升,每走1公里耗费1升油,在f公里处有一个加油站,请问至少要加几次油?
额,能不加油就不加,实在跑不动了就加一次。如此往复贪心即可。(智障的我调了一个半小时才发现自己有一句话只打了前半句。。。)
#include<bits/stdc++.h> using namespace std; typedef long long LL; LL ans=0,a,b,f,k,oil; int main(){ scanf("%I64d%I64d%I64d%I64d",&a,&b,&f,&k); oil=b; if(b<f||b<a-f){printf("-1");return 0;} for(int i=1;i<=2*k;i++){ if(i%4==1||i%4==2){ if(i&1){ if(oil<f){printf("-1");return 0;} oil-=f; } else { if(i==2*k){ if(oil<a-f)ans++; break; } else{ if(b<2*(a-f)){printf("-1");return 0;} if(oil<2*(a-f))ans++,oil=b; oil-=(a-f); } } } else{ if(i&1){ if(oil<a-f){printf("-1)");return 0;} oil-=(a-f); } else{ if(i==2*k){ if(oil<f)ans++; break; } else{ if(b<2*f){printf("-1");return 0;} if(oil<2*f)ans++,oil=b; oil-=f; } } } } printf("%I64d",ans); return 0; }
D. Make a Permutation!
题意:给你一个由小于n的正整数组成的数组,问你至少得替换多少个元素才能使它成为一个全排列,并输出替换次数最少时字典序最小的全排列
明显贪心。。。。(只要你不把一些小学生都会的东西写反就行了)
#include<bits/stdc++.h> using namespace std; #define MAXN 200000+10 int n,a[MAXN],cnt[MAXN],st[MAXN],vis[MAXN],top=0; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++; for(int i=1;i<=n;i++) if(!cnt[i])st[++top]=i; int p=1; for(int i=1;i<=n;i++){ if(p>top)break; int x=st[p]; if(!vis[x]&&!cnt[x]){ if(a[i]>x&&cnt[a[i]]!=1){ cnt[a[i]]--; a[i]=x; vis[x]=1; cnt[x]++; p++; } else if(a[i]<=x){ if(!vis[a[i]])vis[a[i]]=1; else{ cnt[a[i]]--; a[i]=x; vis[x]=1; cnt[x]++; p++; } } } } printf("%d\n",top); for(int i=1;i<=n;i++)printf("%d ",a[i]); return 0; }
E. Fire
题意:Polycarp家的房子着火了。在他的家中有n件物品,第i件价值为pi,抢救它所用的时间为ti,且只能在di时间之前抢救。问救出哪几件物品能使抢救的价值最大?
经典的排序背包问题,对di进行排序之后跑一遍背包并记录路径即可。
#include<bits/stdc++.h> using namespace std; #define MAXN 110 struct item{int t,d,p,id;}a[MAXN]; int n,last,top=0,dp[MAXN][2500],ch[MAXN][2500],picked[2500]; bool cmp(item a,item b){return a.d<b.d;} int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].t,&a[i].d,&a[i].p),a[i].id=i; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++){ last=0; for(int j=1;j<=2001;j++){ if(j<a[i].d&&j>=a[i].t&&dp[i-1][j-a[i].t]+a[i].p>=dp[i-1][j]){ dp[i][j]=dp[i-1][j-a[i].t]+a[i].p; ch[i][j]=1; } else dp[i][j]=dp[i-1][j]; if(dp[i][j]>=dp[i][last])last=j; } } printf("%d\n",dp[n][last]); for(int i=n;i;i--) if(ch[i][last]){ picked[++top]=a[i].id; last-=a[i].t; } printf("%d\n",top); for(int i=top;i;i--)printf("%d ",picked[i]); return 0; }
Hello World