N个玩家在玩一个游戏。游戏中有两个不同的地图。对于每个玩家,我们都知道他们在每张地图上的实力。当两名玩家在一张特定地图上战斗时,在该地图上力量较高的玩家总是获胜。没有两名玩家在同一张地图上拥有相同的实力。你是游戏大师,想要组织一场比赛。总共会有n-1场战斗。当比赛中有不止一名玩家时,选择任意一张地图,任意两名剩下的玩家在上面战斗。输掉比赛的选手将被淘汰出局。最后,只有一名选手会留下来,他被宣布为比赛的冠军。每位选手决定他是否能赢得比赛。输入第一行包含一个整数t (1 <t< 100)——测试用例的数量。测试用例的描述如下。每个测试用例的第一行包含一个整数n (1 <n < 105)——玩家的数量。每个测试用例的第二行包含n个整数a1, a2,, an (1 < ai < 10°,ai a;对于I j),其中a;是第一张地图上第i个玩家的实力。每个测试用例的第三行包含n个整数b1, b2, ., bn (1 <b;< 109, b;b;对于I j),其中b;是第二张地图上第i个玩家的实力。它保证所有测试用例的n和不超过105。输出对于每个测试用例打印一个长度为n的字符串,如果第i个玩家能够赢得比赛,第i个字符应该是“1”,否则是“O”。
Example
input
Copy
3 4 1 2 3 4 1 2 3 4 4 11 12 20 21 44 22 11 30 1 1000000000 1000000000
output
Copy
0001 1111 1
题解:
首先我们可以知道一个地图上,力量最大的一定可以获得最终胜利,不需要在另一张图上比较了,
假设玩家1,2,如果某张地图1可以战胜2,连接一条2到1的边,如果2最终可以获得胜利,那么1肯定也可以获得胜利
因此我们把每张图的力量按从大到小排序,连接一条条i <- i + 1的有向的
并且从某张地图最大力量id开始遍历,要是遍历过,代表此id可以赢得游戏
#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
int a[100050];
int b[100050];
int id[100050];
vector<int> p[100050];
int vis[100050];
int cmpa(int x,int y)
{
return a[x] > a[y];
}
int cmpb(int x,int y)
{
return b[x] > b[y];
}
void dfs(int x)
{
if(vis[x])
return ;
vis[x] = 1;
for(auto ne:p[x])
{
if(!vis[ne])
dfs(ne);
}
}
void solve()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
}
for(int i = 1;i <= n;i++)
{
scanf("%d",&b[i]);
}
for(int i = 1;i <= n;i ++)
{
p[i].clear();
id[i] = i;
vis[i] = 0;
}
sort(id+1,id + 1 + n,cmpa);
for(int i = 1;i < n;i++)
{
p[id[i + 1]].push_back(id[i]);
}
sort(id + 1,id + 1 + n,cmpb);
for(int i = 1;i < n;i++)
{
p[id[i + 1]].push_back(id[i]);
}
dfs(id[1]);
for(int i = 1;i <= n;i++)
{
if(vis[i])
printf("1");
else
printf("0");
}
printf("\n");
}
//1 2 4
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
scanf("%d",&t);
while (t--)
{
solve();
}
return 0;
}
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//0 1 1 1 1
//0 1 1 1 1