C. Game Master
题意:一共有$n$个人,每个人在$A$图和$B$图中拥有不一样的战斗力,每次战斗战胜对手的条件是战斗力大于对方。判断每个人是否能通过上帝视角的任意安排$n-1$次战斗使其留在最后,如果可以则输出$1$,否则输出$0$。
分析:我们可以将比赛倒过来看,假设从两张地图战斗力最大的出发,那么如果只有$1$次战斗那么两张地图的最大实力者一定能留下来,因为第一张地图选手和第二张地图选手都可以在各自地图碾压。那么我们将其放入容器$set$之中表示其一定可以通过操作留到最后。然后从两张地图的次最高战斗力出发,同样将他们放入$set$之中,依次进行第$3$…第$n-1$次战斗。一旦出现$set.size()==i$次战斗的$i$我们即退出循环战斗。证明:如果$set.size()==i$时,说明在这$i$个回合中能留到最后的只有在第一张和第二张图中战斗力都是前$i$大的数,那么自然剩下的$i+1$~$n-1$次战斗我们不用判定了,因为剩下的数无论如果也打不过前$i$个数中任意一个所以必定无法留在最后。举几个形象的例子加深理解:
1:
两张地图都是$A$选手最大,其余选手不可能获胜。set.size()==i(i=1)不用继续进行
2:
新入$set$的$C$选手可以在$B$解决掉$A$之后被$C$解决。set.size()!=i(i=2)可以继续进行
3:
新入$set$的选手$D$可以在例二前提下,本回合解决掉$A$。set.size()!=i(i=3)可以继续进行
......
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define re register int
#define int long long
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define lowbit(x) (x&-x)
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=1e5+10;
pair<int,int> a[N],b[N];
char s[N];
signed main(){
int t;
cin>>t;
set<int>S;
while(t--){
S.clear();
int n;
cin>>n;
for(int i=0;i<n;i++){cin>>a[i].first;a[i].second=i;}
for(int i=0;i<n;i++){cin>>b[i].first;b[i].second=i;s[i]='0';}
sort(a,a+n);
sort(b,b+n);
for(int i=n-1;i>=0;i--){
S.insert(a[i].second);
S.insert(b[i].second);
if(S.size()==n-i)break;
}
for(auto x:S){
s[x]='1';
}
for(int i=0;i<n;i++)cout<<s[i];
cout<<endl;
}
return 0;
}
这题的确挺有意思的,这场质量很高
被暴打