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

    Problem A:

    题目大意:给你一个由0,1组成的字符串,如果有相邻的0和1要消去,问你最后还剩几个字符。

    写的时候不想看题意直接看样例,结果我以为是1在前0在后才行,交上去错了。。后来仔细

    看了看,哎。以后不能自以为是啊。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2*1e5+2;
    char s[N];
    bool vis[N];
    int main()
    {
        int n;
        scanf("%d%s",&n,s);
        int cnt=n;
        int cnt1=0,cnt0=0;
        for(int i=0;i<n;i++)
        {
            if(s[i]=='0') cnt0++;
            else cnt1++;
        }
        printf("%d
    ",max(cnt0-cnt1,cnt1-cnt0));
    }
    View Code

    Problem B:

    题目大意:给你n个一排的齿轮,每个齿轮有编号(0->n-1)的锯齿,问你能不能转动第一个轮子,

    使其向上的锯齿依次为,0,1,2,3...n-1。水题,你就把第一个齿轮转到0的次数记录下来,第偶数

    个加上,奇数个减去,判断一下。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1005;
    int a[N];
    int main()
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        int cnt=n-a[0];
        //printf("%d
    ",cnt);
        for(int i=1;i<n;i++)
        {
            if(i%2)
            {
                if((a[i]-cnt+n)%n!=i)
                {
                    puts("No");
                    return 0;
                }
            }
            else
            {
                if((a[i]+cnt+n)%n!=i)
                {
                    puts("No");
                    return 0;
                }
            }
        }
        puts("Yes");
        return 0;
    }
    View Code

    Problem C:

    题目大意:给你n个编号1->n的杯子,编号代表了它们的大小,只有大的能套在小的上,现在

    给你这些杯子现在的情况,让你把他变成1<-2<-3<-4....<-n这种形式需要操作几次。简单模拟

    一下就好了。

    #include<bits/stdc++.h>
    using namespace std;
    int n,k,ans,st;
    int pre[100005];
    void Find(int x)
    {
        if(pre[x]!=x)
        {
            Find(pre[x]);
            ans++;
            pre[x]=x;
        }
    }
    void judge(int now,int p)
    {
        if(now==p+1 || p==-1)
        {
            st=now;
            judge(pre[now],now);
        }
    }
    int main()
    {
        cin>>n>>k;
        for(int i=1;i<=n;i++) pre[i]=i;
        for(int i=1;i<=k;i++)
        {
            int m;
            scanf("%d",&m);
            int p=-1;
            while(m--)
            {
                int g;
                scanf("%d",&g);
                if(p!=-1)
                {
                    pre[p]=g;
                }
                p=g;
            }
        }
        ans=0;
        st=1;
        judge(1,-1);
        Find(st);
        for(int i=st+1;i<=n;i++)
        {
            Find(i);
            pre[i-1]=i;
            ans++;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    Problem D:

    题目大意:有n个排成以行的小道他们的范围分别是(l[i]->r[i])且l[i+1]>r[i],现在有m个长度为b[i]的桥

    两个岛能加上长度为a的桥当且仅当 r[i+1]-l[i]>=a>=l[i+1]-r[i]。问你能不能完成这个工作。

    这个题很显然,可以转换成这个问题:有n-1个区间,m个数,每个数最多只能用一次,第i个数只

    要能被第j个区间包含,那么这个数就可以放入这个区间内。求出,当所有区间里都恰有一个数时的情况。

    我写的时候一直在想固定最大范围和最小范围来贪心,用桥去满足他们,这种方法是不对的。

    思路:我们可以将区间按按l排序,桥按长度排序,然后将当前满足 r>=a>=l 的区间都加到优先队列

    里面,每次取出r最小的区间,这个桥就搭在这个区间上,为什么呢,因为对于优先队列里面的区间

    来说,当前及以后的桥都满足,len[i]>=l 所以可以不用考虑区间的l,这样我们显然就可以贪心地取

    r小的区间。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2*1e5+5;
    struct node
    {
        ll mx,mn;
        int id;
        bool operator <(const node&t) const
        {
            return mx>t.mx;
        }
    }w[N];
    bool cmp(node a,node b)
    {
        return a.mn<b.mn;
    }
    struct num
    {
        ll v;
        int id;
        bool operator <(const num &t)const
        {
            return v<t.v;
        }
    }a[N];
    ll ans[N];
    int n,m;
    int main()
    {
        cin>>n>>m;
        ll pl=-1,pr=-1;
        for(int i=0;i<n;i++)
        {
            ll l,r;
            scanf("%I64d%I64d",&l,&r);
            if(pl!=-1)
            {
                //printf("%d**
    ",i);
                w[i].mx=r-pl;
                w[i].mn=l-pr;
                w[i].id=i;
            }
            pl=l,pr=r;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%I64d",&a[i].v);
            a[i].id=i;
        }
        sort(a+1,a+1+m);
        sort(w+1,w+n,cmp);
        //for(int i=1;i<=m;i++) printf("%I64d ",a[i].v);
        //puts("");
        //for(int i=1;i<n;i++) printf("[%I64d,%I64d] ",w[i].mn,w[i].mx);
        priority_queue<node> Q;
        int cnt=0;
        for(int i=1,j=1;i<=m;i++)
        {
            while(w[j].mn<=a[i].v && a[i].v<=w[j].mx && j<n)
            {
                Q.push(w[j]);
                j++;
            }
            if(Q.empty()) continue;
            node now=Q.top();Q.pop();
            if(a[i].v>now.mx)
            {
                puts("No");
                return 0;
            }
            ans[now.id]=a[i].id;
            cnt++;
        }
        //printf("%d
    ",cnt);
        if(cnt<n-1)
        {
            puts("No");
            return 0;
        }
        puts("Yes");
        for(int i=1;i<n;i++) printf("%I64d%c",ans[i],i==n-1?'
    ' : ' ');
        return 0;
    }
    View Code

    problem E:

    题意:

    有一块n*n大小的巧克力,n<=1e9。现在进行操作,每次都从反对角线上选择一点,然后往上或往左一直吃,

    每当到达巧克力边缘或者下一块已经被吃了,则停止。问你每次操作能吃到几块巧克力。

    思维题,感觉挺难想到了,还是我太菜了。。

    思路:我们考虑从j列往上吃巧克力,吃掉的个数受什么影响呢,肯定不受<j的列印象,对它有直接影响的就

    他右边第一个有操作的点,如果这个点的操作时向左吃,则从j列向上吃只能吃到有操作点的那一行,如果右边

    第一个有操作的点是向上吃,则j列吃的和它一样。

    #include<bits/stdc++.h>
    using namespace std;
    map<int,int> u,l;
    int n,q;
    int main()
    {
        cin>>n>>q;
        while(q--)
        {
            int x,y;
            char s[3];
            scanf("%d%d%s",&x,&y,s);
            map<int,int>::iterator p;
            if(s[0]=='U')
            {
                int ans=0;
                p=u.lower_bound(x);
                if(u.count(x))
                {
                    puts("0");
                    continue;
                }
                if(p==u.end()) ans=y;
                else ans=y-(p->second);
                printf("%d
    ",ans);
                l[y]=x;
                u[x]=y-ans;
            }
            else
            {
                int ans=0;
                p=l.lower_bound(y);
                if(l.count(y))
                {
                    puts("0");
                    continue;
                }
                if(p==l.end()) ans=x;
                else ans=x-(p->second);
                printf("%d
    ",ans);
                u[x]=y;
                l[y]=x-ans;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Extjs知识点汇总
    div设置滚动条内容任然显示不全
    win7 系统安装 docker
    docker常用命令
    cargo实现自动化部署远程jetty容器(非安全模式)
    win7 失去焦点解决方案
    jeecms 评论相关
    jeecms v8 网站访问量配置
    python——进程池
    python多进程编程常用到的方法
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7225837.html
Copyright © 2011-2022 走看看