CodeForces Round#480 div3

很久很久没有写过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;
}

猜你喜欢

转载自blog.csdn.net/z_sea/article/details/80315171