CF组赛补题-Game Master

nn players are playing a game.

There are two different maps in the game. For each player, we know his strength on each map. When two players fight on a specific map, the player with higher strength on that map always wins. No two players have the same strength on the same map.

You are the game master and want to organize a tournament. There will be a total of n−1n−1 battles. While there is more than one player in the tournament, choose any map and any two remaining players to fight on it. The player who loses will be eliminated from the tournament.

In the end, exactly one player will remain, and he is declared the winner of the tournament. For each player determine if he can win the tournament.

Input

The first line contains a single integer tt (1≤t≤1001≤t≤100) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer nn (1≤n≤1051≤n≤105) — the number of players.

The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109, ai≠ajai≠aj for i≠ji≠j), where aiai is the strength of the ii-th player on the first map.

The third line of each test case contains nn integers b1,b2,…,bnb1,b2,…,bn (1≤bi≤1091≤bi≤109, bi≠bjbi≠bj for i≠ji≠j), where bibi is the strength of the ii-th player on the second map.

It is guaranteed that the sum of nn over all test cases does not exceed 105105.

Output

For each test case print a string of length nn. ii-th character should be "1" if the ii-th player can win the tournament, or "0" otherwise.

题目类型:百思不解题:)

解题知识:

        1)unique()函数

         unique函数的功能是元素去重。即”删除”序列中所有相邻的重复元素(只保留一个),在使用unique函数之前,一般都会将目标序列进行排序

常用形式:

1

iterator unique(iterator it_1,iterator it_2);

其中这两个参数表示对容器中[it_1,it_2)范围的元素进行去重

(注:区间是前闭后开,即不包含it_2所指的元素)

返回值是一个迭代器,它指向的是去重后容器中不重复序列的最后一个元素的下一个元素

unique函数的去重过程实际上就是不停的把后面不重复的元素移到前面来(也可以说是用不重复的元素占领重复元素的位置)

2)C++ lower_bound()函数

        lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。

//在 [first, last) 区域内查找不小于 val 的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                             const T& val);
//在 [first, last) 区域内查找第一个不符合 comp 规则的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                             const T& val, Compare comp);

该函数还会返回一个正向迭代器。当查找成功时,迭代器指向找到的元素;

                                                      反之,如果查找失败,迭代器的指向和 last 迭代器相同。

该函数仅适用于已排好序的序列。

所谓“已排好序”,指的是 [first, last) 区域内所有令 element<val(或者 comp(element,val),其中 element 为指定范围内的元素)成立的元素都位于不成立元素的前面。

解题思路:1)先去重。(记得排序)这也是 我不明白的地方,明明题目说(No two players have the same strength on the same map)

                  2)根据去重后的序列A, 对算出i 在地图A的手下败将有几个,存入p[i].a中

                        根据去重后的序列B, 对算出i 在地图B的手下败将有几个,存入p[i].b中

                3)根据地图A的能力排序,则p[i]关于a非降序。

                      累加能打败的人数,当ans1 == ans2 时,说明

            for(int i =1; i<n; i++)
			{
				ans1 += p[i].a;//up 
				ans2 += p[i].b;
				if(ans1 == ans2) f = i+1;
				//能打败的人数相同说明,i在a, b场中在[1, i]这个集合中是最强的。
                   在当前的下标为i的人及其i以下的人因a, b场能力已经能得到一个绝对冠军了 
			}
			for(int i =f; i<=n; i++)
			{
				p[i].w = 1;//f以后的人一定至少在a场能力递增
                一定存在ans1 != ans2, 有人在 A场或者B场中有 超越另一场的发挥
                因此能打败一些在另一场中无法打败的人,所以有可能赢
			}

错误代码:

#define inf 0x3f3f3f3f
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;

int main()
{
	int t ;
	string ans;
	cin>>t;
	while(t -- )
	{
		int n;
		cin>>n;
		int win[n];
		vector<int> v1, v2;
		for(int i = 0; i<n; i++) 
		{
			int temp;
			cin>>temp;
			v1.push_back(temp);
		}
		for(int i = 0; i<n; i++) 
		{
			int temp;
			cin>>temp;
			v2.push_back(temp);
		}
		if(n == 1)
		{
			cout<<1<<endl;
			continue;
		}
		int maxPos1 = max_element(v1.begin(),v1.end()) - v1.begin(); 
		int minPos1 = min_element(v1.begin(),v1.end()) - v1.begin();
		int maxPos2 = max_element(v2.begin(),v2.end()) - v2.begin(); 
		int minPos2 = min_element(v2.begin(),v2.end()) - v2.begin();
		bool flag = false;
		if(maxPos1 == maxPos2)
		{
			memset(win, 0, sizeof(win));
			win[maxPos1] = 1;
		}
		else if(minPos1 == minPos2) 
		{
			memset(win, 1, sizeof(win));
			win[minPos1] = 0;
		}
		else
		{
			flag = true;
			for(int i =0; i<n; i++) cout<<1;
		}
		
		for(int i =0; i<n && !flag; i++)
		{
			cout<<win[i]; 
		}
		cout<<endl;
	 } 
	return 0;
}

AC代码:

#define inf 0x3f3f3f3f
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
typedef long long ll;
struct node
{
	int a, b, inx, w;
	bool operator<(const node&x)const{
		return a < x.a;	
	}
}p[N];
int a[N], b[N];
int A[N], B[N];
bool cmp(node &a, node &b){
	return a.inx < b.inx;
}
int main()
{
	int t ;
	cin>>t;
	while(t -- )
	{
		int n;
		cin>>n;
		for(int i =1; i<= n; i++) p[i].w = 0; 
 		for(int i = 1; i<=n; i++) cin>>a[i],A[i] = a[i];
		for(int i = 1; i<=n; i++) cin>>b[i], B[i] = b[i];
		sort(A+1, A+n+1);
		sort(B+1, B+1+n);
		int index1 = unique(A+1, A+n+1)-A-1;
		int index2 = unique(B+1, B+n+1)-B-1;
		/*用来去重,获取a, b存当前下标为i,能力为a[i]的人能打败的人数*/
		for(int i =1; i<=n;i++)
		{
			p[i].inx = i;
			//lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。
			p[i].a = lower_bound(A+1, A+1+index1, a[i])-A; 
			p[i].b = lower_bound(B+1, B+1+index2, b[i])-B;
		}
			sort(p+1, p+1+n);//按地图a能力排序 
			int ans1 = 0, ans2 = 0;
			int f = 1;
			
			for(int i =1; i<n; i++)
			{
				ans1 += p[i].a;//up 
				ans2 += p[i].b;
				if(ans1 == ans2) f = i+1;
				//能打败的人数相同说明,i在a, b场中在[1, i]这个集合中是最强的
                //在当前的下标为i 的人及其i以下的人因a, b场能力已经能得到一个绝对冠军了 
			}
			for(int i =f; i<=n; i++)
			{
				p[i].w = 1;
			}
			//output 按下标排序 
			sort(p+1, p+1+n, cmp);
			for(int i =1; i<=n; i++)
				cout<<p[i].w;
			cout<<endl;
		
	 } 
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sqli-labs-master是一个SQL注入练习平台,第一关是一个基础的SQL注入练习。 首先,打开练习平台,找到第一关的链接。在链接的末尾加上 `'`,观察页面的响应。如果页面存在SQL注入漏洞,那么会显示类似如下的错误信息: ``` You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1 ``` 这意味着我们在SQL语句中注入了一个单引号,导致MySQL服务器无法正确解析SQL语句。这也是SQL注入漏洞的典型表现。 接下来,我们可以尝试利用注入漏洞获取数据库中的数据。在第一关中,我们需要获取 `users` 表中的数据。因此,我们可以在链接的末尾加上以下语句: ```sql ' union select 1,2,3,4,5,6,7,8-- ``` 这个语句会在SQL语句中插入一个 `union` 查询语句,用于查询 `users` 表中的数据。`1` 到 `8` 是查询的字段数量,这里可以根据实际情况调整。双破折号 `--` 表示注释,用于避免语法错误。 将以上语句加到链接末尾后,点击访问链接,页面会显示类似以下内容的数据: ``` 1 2 3 4 5 6 7 8 1 admin 5f4dcc3b5aa765d61d8327deb882cf99 1 2 bob 202cb962ac59075b964b07152d234b70 0 ``` 其中,第一行是查询结果的字段名,第二行开始是 `users` 表中的数据。我们可以看到,这个表中包含了两个用户的信息,其中 `admin` 用户的密码经过了 MD5 加密。 这样,我们就成功地利用 SQL 注入漏洞获取了数据库中的数据,完成了第一关的挑战。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值