第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)L Let‘s Play Curling

题目

题目描述
Curling is a sport in which players slide stones on a sheet of ice toward a target area. The team with the nearest stone to the center of the target area wins the game.

Two teams, Red and Blue, are competing on the number axis. After the game there are (n+m)(n+m) stones remaining on the axis, nn of them for the Red team and the other mm of them for the Blue. The ii-th stone of the Red team is positioned at \(a_i\) and the i-th stone of the Blue team is positioned at \(b_i\)

Let c be the position of the center of the target area. From the description above we know that if there exists some i such that \(1≤i≤n\) and for all \(1≤j≤m\) we have \(|c - a_i| < |c - b_j|\)

then Red wins the game. What's more, Red is declared to win pp points if the number of i satisfying the constraint is exactly p.

Given the positions of the stones for team Red and Blue, your task is to determine the position cc of the center of the target area so that Red wins the game and scores as much as possible. Note that cc can be any real number, not necessarily an integer.
输入描述:
There are multiple test cases. The first line of the input contains an integer TT indicating the number of test cases. For each test case:

The first line contains two integers nn and mm \((1 \le n, m \le 10^5)\) indicating the number of stones for Red and the number of stones for Blue.

The second line contains nn integers \(a_1, a_2, \cdots, a_n\)\((1 \le a_i \le 10^9)\) indicating the positions of the stones for Red.
The third line contains mm integers \(b_1, b_2, \cdots, b_m\)\((1 \le b_i \le 10^9)\) indicating the positions of the stones for Blue.

It's guaranteed that neither the sum of n nor the sum of m will exceed \(5 \times 10^5\).
输出描述:
For each test case output one line. If there exists some cc so that Red wins and scores as much as possible, output one integer indicating the maximum possible score of Red (NOT cc). Otherwise output "Impossible" (without quotes) instead.
示例1
输入
3
2 2
2 3
1 4
6 5
2 5 3 7 1 7
3 4 3 1 10
1 1
7
7
输出
2
3
Impossible
备注:
For the first sample test case we can assign c = 2.5c=2.5 so that the stones at position 2 and 3 for Red will score.

For the second sample test case we can assign c = 7c=7 so that the stones at position 5 and 7 for Red will score.

题意

给定一个长度为n的a数组和长度为m的b数组,每个数组中的数代表着当前各个队伍有的stone的位置。选定一个位置c,如果存在一个红队的石头到c的距离小于所有蓝队的石头到c的距离,那么红队积一分,问c选最合适的地方的时候红队的最高得分是多少,如果不存在方案则输出Impossible

思路

把b数组的每一项之间想象成一个“框” :先对a和b进行排序
\((1)\) 当b取第一项的时候,由于c可以取任意实数(包括小数和整数),就取0到b[0] 为第一个区间,c设在0的位置,这样小于b[0]的a都是满足条件的a 因为所有的b离当前的a都大于等于b[0] ,而 小于b[0]的这些a离c的距离又小于b[0]。,每次算完一项都把算过的a去掉。

\((2)\) 当b取\((1->n-1)\)的时候这里的n-1便是最后一项,由于之前算过的a都已经从数组去除掉,所以只需要把c放到前一项的地方,即统计b[i-1] 到 b[i] 之间有多少个符合条件的a

\((3)\) 最后留下来的b肯定都是大于b[n-1] 即最后一项的,于是把c设在\(+∞\) ,每次算出来cnt后都更新一下最大值即可

\((4)\) 需要注意的是a和b相等的时候需要把a直接去除

代码

#include <bits/stdc++.h>
using namespace std;
queue<int>Qa,Qb;

const int maxn = 100000+1000;

int a[maxn],b[maxn];

void Solve()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++) scanf("%d",&b[i]);
	
	sort(a+1,a+1+n);
	sort(b+1,b+1+m);
	
	for(int i=1;i<=n;i++) Qa.push(a[i]);
	for(int i=1;i<=m;i++) Qb.push(b[i]);
	
	int ans = 0;
	while(!Qb.empty())
	{
		int cnt = 0;
		while(!Qa.empty() && Qa.front() < Qb.front())//记录0-b_1 或者 b_i 到 b_i+1 之间有多少个a 
		{
			Qa.pop();
			cnt++;
		}
		ans = max(ans,cnt); 
		while(!Qa.empty() && Qa.front() == Qb.front())
		Qa.pop();
		Qb.pop();
		
	}
	int s = Qa.size(); // 记录靠近正无穷的a的数量最大值 
	ans = max(ans,s);
	if(ans==0)
	printf("Impossible");
	else
	printf("%d",ans);
	while(Qa.size()) Qa.pop();
	while(Qb.size()) Qb.pop();
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		Solve();
		if(t) puts("");
	}
} 
posted @ 2020-12-21 17:06  墨墨墨小白iiy💭💡🎈  阅读(327)  评论(0编辑  收藏  举报