很久很久没有写过CF的题解了。我可能也就在CF DIV3里面一展拳脚了。其他的也就签到一下,就没有然后。
认真想了想,其实这一套题都不难,但是为什么我只能做三题呢,很大程度就是卡题对我影响太大,而且自己做题,
没有队友的翻译,读题也是一个问题了。D题也就暴力,但是我真的没想到,我以前的想法都是沾边,但是要是我自己
想下去可能就可以沾到答案了。。。以致后面的E、F、G没读题,也没做。太吃力了英语题。。。我只能问问别人是什么意思
才会做下去,不然我一定做不了了。这是我第一次在CF上写的一次全题解。
A:问题是 给你N 个元素,去重后 按照最后一个出现的位置排序,也就是从右往左出现的顺序。
这一题有一点取巧,但是不难想,就是和我们平时去重一样,但是这次是从右往左的顺序来标记 放进数组,
然后输出即可。代码是用Set来练手罢了,其实开一个vis数组也是挺不错的。
#include<bits/stdc++.h> using namespace std; int main() { int n; int a[100005]={0}; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); } set<int>S; int b[1005],cnt=0; for(int i=n-1;i>=0;i--){ if(S.count(a[i])==0){ S.insert(a[i]); b[cnt++]=a[i]; } } printf("%d\n",cnt); for(int i=cnt-1;i>=0;i--){ printf("%d%c",b[i],i==0?'\n':' '); } return 0; }
B、比A题还水,它的问题直接要你找多少组 XXX连在一起 。
一个for循环解决:
#include<bits/stdc++.h> using namespace std; int main() { string s; int n; scanf("%d",&n); cin>>s; int ans=0; for(int i=2;i<s.size();i++){ if(s[i]=='x'&&s[i-1]=='x'&&s[i-2]=='x'){ ans++; } } printf("%d\n",ans); return 0; }
C、题意:有N个宿舍楼,里面有a[1~n]个宿舍,然后它们都是连在一起的,就是说
一号楼最后一个房间和二号楼第一个房间的号码是相邻的。
问题是 给你一个数,要你判断是几号楼第几个房间,其实这个应该要用二分。但是这题好像数据用不上。
前缀和+二分
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll sum[200500],a[200500],b[200500]; ll n,m; int low_bound(ll x){ int L=1,R=n,mid; while(L<R){ mid=(L+R)/2; if(sum[mid]>=x){ R=mid; }else{ L=mid+1; } } return L; } int main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); sum[i]=sum[i-1]+a[i]; }for(int i=1;i<=m;i++){ scanf("%lld",&b[i]); } for(int i=1;i<=m;i++){ ll ans1,ans2; ans1=lower_bound(sum+1,sum+n+1,b[i])-sum; ans2=b[i]-sum[ans1-1]; printf("%lld %lld\n",ans1,ans2); } return 0; }
D、给你一个数列,要你构造一个等差数列,你只能对 任一个数进行+1或者-1
问:如果能构造 请输出 最小的改变数,要是不能,请输出-1
#include<bits/stdc++.h> using namespace std; int main() { int n,b[100010]; while(~scanf("%d",&n)){ for(int i=0;i<n;i++){ scanf("%d",&b[i]); } if(n==1||n==2){printf("0\n");continue;} int L=b[0],R=b[n-1]; int ans=0x3f3f3f3f,i,j,tL,tR; for(i=-1;i<=1;i++){ for(j=-1;j<=1;j++){ int tmp=0; if(i!=0)tmp++; if(j!=0)tmp++; tL=L+i; tR=R+j; //cout<<" TL :"<<tL<<" "<<" TR :"<<tR<<" "<<"i ,j: "<<i<<" "<<j<<endl; if((tR-tL)%(n-1)!=0) continue; int d=(tR-tL)/(n-1),k; for(k=1;k<n-1;k++){ if(abs(b[k]-(tL+k*d))<=1){ if(b[k]-(tL+k*d)!=0){ tmp++; //cout<<b[k]<<endl; } }else{ break; } } // cout<<tmp<<endl; if(k==n-1){ ans=min(tmp,ans); } } } if(ans==0x3f3f3f3f){ printf("-1\n"); }else{ printf("%d\n",ans); } } return 0; }
E、讲述了n个公交车站,有a[1~n]个数字,容量为W
<0 是下车
>0 是上车
=0 飞站。
问你最初 在车上有多少种情况。纯属猜题,看了错误示例。
#include<bits/stdc++.h> using namespace std; int main() { int n,w,a[1060]; while(~scanf("%d%d",&n,&w)){ int sum[1050]={0}; int maxz=-1,minz=0x3f3f3f3f,flag=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; if(sum[i]>0&&flag==0){ flag=1; }else if(sum[i]<0&&flag==0){ flag=-1; }else if(flag!=0&&sum[i]*flag<0){ flag=2; } maxz=max(maxz,sum[i]); minz=min(minz,sum[i]); } if(maxz==minz&&maxz==0){ printf("%d\n",w+1); }else if(flag==2) printf("%d\n",(w-(maxz-minz)+1)>0?w-(maxz-minz)+1:0); else if(flag==1){ printf("%d\n",(w+1-maxz)>0?w+1-maxz:0); }else if(flag==-1){ printf("%d\n",(w+1+minz)>0?w+1+minz:0); } } return 0; }
F、题意:有n个人, 每一个人有一个能力值, 然后求这个能力值高的人能当能力值低的人的导师,
然后又m对人在吵架, 如果2个人吵架, 他们2个人就不能组成导师关系,
现在求每个人可以当多少个人的导师数目。
看代码实现,排序+lowerbound
#include<bits/stdc++.h> using namespace std; typedef struct node{ int x,num,No; }node; int cmp1(node a,node b){ if(a.x==b.x){ return a.No<b.No; } return a.x<b.x; } int cmp2(node a,node b){ return a.No<b.No; } int main() { int n,m; while(~scanf("%d%d",&n,&m)){ node a[200050]; int b[200050]={0}; for(int i=0;i<n;i++){ scanf("%d",&a[i].x); b[i]=a[i].x; a[i].num=0; a[i].No=i; } int u,v; while(m--){ scanf("%d%d",&u,&v); if(a[u-1].x>a[v-1].x){ a[u-1].num--; }else if(a[u-1].x<a[v-1].x){ a[v-1].num--; } } sort(a,a+n,cmp1); sort(b,b+n); for(int i=0;i<n;i++){ a[i].num+=(lower_bound(b,b+n,a[i].x)-b); } sort(a,a+n,cmp2); for(int i=0;i<n;i++){ printf("%d%c",a[i].num,i==n-1?'\n':' '); } } return 0; }
G题:贪心加模拟
给你N天,M门科目。
m门科目有 s d c- s知道这门学科考试时间, d-考试时间,c复习时间。
问你每一天怎么复习,要是不行就输出-1。
#include<bits/stdc++.h> using namespace std; typedef struct node{ int s,d,c,id; }node; node a[1000]; int n,m; int cmp(node a,node b){ return a.d<b.d; } int main() { while(~scanf("%d%d",&n,&m)){ int data[10005]={0}; int flag=1; for(int i=1;i<=m;i++){ scanf("%d%d%d",&a[i].s,&a[i].d,&a[i].c); a[i].id=i; if(data[a[i].d]==m+1){ flag=0; }else{ data[a[i].d]=m+1; } } sort(a+1,a+1+m,cmp); int cur=1; for(int i=1;i<=n;i++){ if(data[i]==m+1){ continue; } else if(i<a[cur].s&&data[i]==0){ for(int j=cur;j<n;j++){ if(i>=a[j].s&&a[j].c&&i<a[j].d){ data[i]=a[j].id; a[j].c--; break; } } continue; }else if(a[cur].s<=i&&a[cur].c&&data[i]==0&&i<a[cur].d){ data[i]=a[cur].id; a[cur].c--; }else if(a[cur].s<=i&&a[cur].c&&data[i]){ flag=0;break; } if(a[cur].c==0){ cur++; } if(cur==m+1){ break; } } for(int i=1;i<=m;i++){ if(a[i].c){ flag=0; } } /*for(int i=1;i<=n;i++){ printf("%d%c",data[i],i==n?'\n':' '); }*/ if(flag){ for(int i=1;i<=n;i++){ printf("%d%c",data[i],i==n?'\n':' '); } }else{ printf("-1\n"); } } return 0; }