zoukankan      html  css  js  c++  java
  • Codeforces Round #158 (Div. 2)

    这场的模拟题真的有du!!!

    Problem A

    水题,更新当前对b取模后的余数,直接模拟。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2*1e5;
    int a,b,n;
    char s[N];
    int main()
    {
        scanf("%d%d%d",&a,&b,&n);
        int now=a%b;
        bool flag=true;
        int pos=0;
        for(int i=1;i<=n;i++)
        {
            bool judge=false;
            for(int j=9;j>=0;j--)
            {
                if(((now*10)+j)%b==0)
                {
                    judge=true;
                    now=0;
                    s[pos++]='0'+j;
                    break;
                }
            }
            if(!judge) flag=false;
        }
        s[pos]=0;
        if(flag) printf("%d%s
    ",a,s);
        else puts("-1");
        return 0;
    }
    View Code

    Problem B

    看到第一眼,我不想做了!直接跳到了第三题,其实还好,做完第三题后一发就A了。

    题目大意:给你一串字符串,让你找出出现次数最多的日期,形式 xx-yy-zzzz,且年份

    在2013-2015之间。

    思路:我的写法是开一个vis[6][13][32]的数组记录日期出现过的次数,最后找出最大

    的一个就好了。在找的时候我先找的中间的月份,在向前向后延伸找,其实是可以直接

    十个字符十个字符找,更简单一点。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+3;
    const int d_m[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    char s[N];
    int vis[6][13][32],len;
    void work(int x,int y,int m)
    {
        if(x<=0 || y>len) return;
        if(s[x]!='-' && s[x+1]!='-')
        {
            int now=10*(s[x]-'0')+(s[x+1]-'0');
            if(now<=d_m[m])
            {
                if(s[y-3]=='2' && s[y-2]=='0' && s[y-1]=='1' && s[y]>='3' && s[y]<='5')
                    vis[s[y]-'0'][m][now]++;
                else return;
            }
            else return;
        }
        else return;
    }
    int main()
    {
        scanf("%s",s+1);
        len=strlen(s+1);
        for(int i=1;i+3<=len;i++)
        {
            if(s[i]=='-' && s[i+3]=='-' && ((s[i+1]=='0' && s[i+2]>='1' && s[i+2]<='9') || (s[i+1]=='1' && s[i+2]>='0' && s[i+2]<='2')))
            {
                //printf("%d %c^^^^^
    ",i,s[i]);
                int m=10*(s[i+1]-'0')+(s[i+2]-'0');
                work(i-2,i+7,m);
            }
        }
        int ansv=0,ansy=0,ansm=0,ansd=0;
        for(int i=3;i<=5;i++)
        {
            for(int j=1;j<=12;j++)
            {
                for(int k=1;k<=d_m[j];k++)
                {
                    if(vis[i][j][k]>ansv)
                    {
                        ansv=vis[i][j][k];
                        ansy=i;
                        ansm=j;
                        ansd=k;
                    }
                }
            }
        }
        if(ansd<10) printf("0%d-",ansd);
        else printf("%d-",ansd);
        if(ansm<10) printf("0%d-",ansm);
        else printf("%d-",ansm);
        printf("201%d
    ",ansy);
        return 0;
    }
    View Code

    Problem C

    题目大意:有n个箱子,每个箱子里有若干个小球(可以为0个),有一个操作,选取

    一个箱子i(这个箱子里的小球不能为0),将里面的小球全部都拿出来,一次一个分给

    i+1,i+2...,超过n则分给1,2,3...一直循环知道小球分完,现在给你分完之后各个箱子里的

    小球个数,和最后一个小球分给了哪个箱子x,让你输出原来箱子里德小球数。

    思路:刚开始我以为题目的意思是每个箱子里都至少有一个小球,那么起始位置肯定是

    分完之后最少的那个,然后全部箱子里的小球减去最小值,从起始点开始模拟。wa了几次

    因为箱子里的小球个数可能为0,可以有多个最小值,这样的话,我们可以将各个小球的

    值减去都减去最小值(也就是分小球分过的完整轮数),然后从x从后往前模拟就可以了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll a[100005],mn,n,m;
    int main()
    {
        mn=1e18;
        scanf("%I64d%I64d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d",&a[i]);
            mn=min(mn,a[i]);
        }
        for(int i=1;i<=n;i++)a[i]-=mn;
        ll sum=n*mn;
        while(a[m])
        {
            a[m]--;
            m--;sum++;
            if(m==0)m=n;
        }
        a[m]=sum;
        for(int i=1;i<=n;i++) printf("%I64d%c",a[i],n==i? '
    ':' ');
        return 0;
    }
    View Code

    Problem D

    题目大意:有一棵树,每条边有一个权值,节点的权值等于连接它的各个边的权值的和,

    每个点是黑色或者白色,相邻节点的颜色不能一样。现在只给你,节点的颜色和权值,

    让你求各个边的情况。

    思路:我们先将黑的节点都放一起,白节点也都放一起,然后从小到大排序,每次从

    两堆中分别取出一个,定点权值小的那个肯定是端点,将这两个连边,边的权值为较小

    的节点权值,较大节点继续留下和另一个不同颜色的点比较,一直这样构造下去。

    我好菜啊,没写出来。。。

    #include<bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define P pair
    using namespace std;
    int n;
    vector<P<int,int> > V[2];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int c,s;
            scanf("%d%d",&c,&s);
            V[c].pb(mp(s,i));
        }
        sort(V[0].begin(),V[0].end());
        sort(V[1].begin(),V[1].end());
        for(int i=0,j=0;i<V[0].size() && j<V[1].size();)
        {
            int mn=min(V[0][i].first,V[1][j].first);
            V[0][i].first-=mn;V[1][j].first-=mn;
            printf("%d %d %d
    ",V[0][i].second,V[1][j].second,mn);
            if(V[0][i].first) j++;
            else if(V[1][j].first) i++;
            else if(i+1<V[0].size()) i++;
            else j++;
        }
        return 0;
    }
    View Code

     Problem E

    题目大意:给你一堆点和9个数字(这九个数字的和为点的总数)让你用平行于x轴的两条线

    和平行于y轴的两条线将这些点分为九分,使其与9个数字的任意一种排列一一对应,问你

    有没有这样的一种分法,这题补了好久,我好菜。

    题解:大体思路是先枚举九个数字的每一种排列,然后判断这种排列可不可行。在判断

    每一种排列可不可行的时候,我们可以先判断三行三列的情况,然后再判断其他块中的

    点的数量,这样我们就需要一个工具来快速地知道一个区域内有多少点,这样我们就能

    想到用线段树,以x轴建树,每个节点存y的值,并将这个节点所对应区间的y的值排序。

    详细看代码:

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    using namespace std;
    const int N=1e5+10;
    pii p[N];//存点
    vector<int> st[N<<2];//建树
    int x[N],y[N],n,ax[3],ay[3],b[10],id[10],a[10];//x[N]所有点x的值,y[N]同理;
    void build(int l,int r,int rt)
    {
        for(int i=l;i<=r;i++) st[rt].push_back(p[i].se);
        sort(st[rt].begin(),st[rt].end());
        if(l==r) return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    int query(int x,int y,int l,int r,int rt)
    {
        if(p[l].fi>x) return 0;
        if(p[r].fi<=x)
        {
            return upper_bound(st[rt].begin(),st[rt].end(),y)-st[rt].begin();
        }
        int m=(l+r)>>1;
        return query(x,y,lson)+query(x,y,rson);
    }
    bool judge()
    {
        int sx[3],sy[3];sx[0]=0,sy[0]=0;
        sx[1]=a[1]+a[4]+a[7];sx[2]=sx[1]+a[2]+a[5]+a[8];
        sy[1]=a[1]+a[2]+a[3];sy[2]=sy[1]+a[4]+a[5]+a[6];
        for(int i=1;i<=2;i++)
        {
            if(x[sx[i]]==x[sx[i]+1]) return false;//如果x[sx[i]]==x[sx[i]+1],因为这两个点相等,不能成功分开,这种排列错误;
            if(y[sy[i]]==y[sy[i]+1]) return false;//同上
        }
        int fx[3],fy[3];
        for(int i=1;i<=2;i++) fx[i]=x[sx[i]],fy[i]=y[sy[i]];
        if(query(fx[1],fy[1],1,n,1)!=a[1]) return false;//线段树快速询问;
        if(query(fx[1],fy[2],1,n,1)!=a[1]+a[4]) return false;
        if(query(fx[2],fy[1],1,n,1)!=a[1]+a[2]) return false;
        if(query(fx[2],fy[2],1,n,1)!=a[1]+a[2]+a[4]+a[5]) return false;
        for(int i=1;i<=2;i++) ax[i]=fx[i],ay[i]=fy[i];
        return true;
    }
    /*
    a[1]  a[2]  a[3]
    
    a[4]  a[5]  a[6]
    
    a[7]  a[8]  a[9]
    */
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].fi,&p[i].se);
            x[i]=p[i].fi;y[i]=p[i].se;
        }
        sort(p+1,p+n+1);sort(x+1,x+1+n);sort(y+1,y+1+n);//排序
        for(int i=1;i<=9;i++) scanf("%d",&b[i]),id[i]=i;
        build(1,n,1);
        do
        {
            for(int i=1;i<=9;i++) a[i]=b[id[i]];
            if(judge())//判断这种排列可不可行
            {
                printf("%f %f
    ",ax[1]+0.5,ax[2]+0.5);
                printf("%f %f
    ",ay[1]+0.5,ay[2]+0.5);
                return 0;
            }
        }while(next_permutation(id+1,id+10));//枚举9个数字的排列情况
        puts("-1");
        return 0;
    }
    View Code
  • 相关阅读:
    webapp开发绝对定位引发的问题
    git下配置github sshkey
    html5 filereader读取流注意事项
    神奇的负Margin
    泪奔的ie
    第二次作业-实践一 网络攻防环境的搭建
    20199115 2019-2020-2 《网络攻防实践》第一周作业
    《网络攻防实践》寒假作业
    C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
    getline()函数
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7206099.html
Copyright © 2011-2022 走看看