其他分享
首页 > 其他分享> > CF1608C

CF1608C

作者:互联网

题意:

给定 \(n\) 个人分别在两张地图上的能力值,每次选出其中两人在任意地图上战斗,能力值低者被淘汰,获胜者为最后没被淘汰的那个人,问那些人可以通过控制比赛获胜,那些人一定无法获胜

思路:

考虑那些必败者,要么打不过任何人,要么能打过的人打不过任何人,要么能打过的人能打过的人打不过任何人,以此类推,所以很容易搞出一个 \(O(n^n)\) 的垃圾算法,考虑优化

不妨将两个能力值分别排序,并记录所属编号,从后往前扫,可以发现,如果存在一个位置 \(i\) ,使得分别在两个图中前 \(i\) 强的人都是某 \(i\) 个人,那么它内部一定每个人都能在这 \(i\) 个人的集合中获胜,并且不在这个集合中的任意一个人一定都打不过这个集合里的任意一个人,然后在这 \(i\) 个人的集合中的人一定都能获胜,剩下的必败

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
pair<int,int>a[(int)(1e5+10)],b[(int)(1e5+10)];
set<int>s;
char ans[(int)(1e5+10)];
signed main()
{
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        s.clear();
        for(int i=0;i<=n-1;i++) 
        {
            cin>>a[i].first;a[i].second=i;
        }
        for(int i=0;i<=n-1;i++)
        {
            cin>>b[i].first;b[i].second=i;
            ans[i]='0';
        }
        sort(a,a+n);sort(b,b+n);
        ans[n]=0;
        int i;
        for(i=n-1;i>=0;i--)
        {
            s.insert(a[i].second);
            s.insert(b[i].second);
            if(s.size()==n-i) break;
        }
        while(i<=n-1) ans[a[i].second]='1',i++;
        puts(ans);
    }
}

标签:10,int,CF1608C,second,1e5,ans,获胜
来源: https://www.cnblogs.com/blogbyWHY/p/15680185.html