2019年我能变强组队训练赛第十场 C Criss-Cross Cables(优先队列模拟)

问题 C: Criss-Cross Cables

时间限制: 2 Sec  内存限制: 128 MB
提交: 72  解决: 18
[提交] [状态] [命题人:admin]

题目描述

As a participant in the BAPC (Bizarrely Awful Parties Competition) you are preparing for your next show. Now,you do not know anything about music, so you rip off someone else’s playlist and decide not to worry about that any more. What you do worry about, though, is the aesthetics of your set-up: if it looks too simple, people will be unimpressed and they might figure out that you are actually a worthless DJ.
It doesn’t take you long to come up with a correct and fast solution to this problem. You add a long strip with a couple of useless ports, and add some useless cables between these ports. Each of these cables connects two ports, and these special ports can be used more than once. Everyone looking at the massive tangle of wires will surely be in awe of your awesome DJ skills.
However, you do not want to connect the same two ports twice directly. If someone notices this, then they will immediately see that you are a fraud!
You’ve made a large strip, with the ports in certain fixed places, and you’ve found a set of cables with certain lengths that you find aesthetically pleasing. When you start trying to connect the cables, you run into another problem. If the cables are too short, you cannot use them to connect the ports! So you ask yourself the question whether you’re able to fit all of the cords onto the strip or not. If not, the aesthetics are ruined, and you’ll have to start all over again.

输入

The first line has 2 ≤ n ≤ 5 · 105 and 1 ≤ m ≤ 5 · 105, the number of ports on the strip and the number of wires.
• The second line has integers 0 ≤ x1 < · · · < xn ≤ 109, the positions of the n sockets.
• The third line has m integers l1, . . . , lm, the lengths of the wires, with 1 ≤ li ≤ 109.

输出

Print yes if it is possible to plug in all the wires, or no if this is not possible.

样例输入

复制样例数据

4 4
0 2 3 7
1 3 3 7

样例输出

yes

题意:给出n个接线柱的坐标,m个线的长度,问是否能把所有的线都接上,条件是:不能有多根线接在相同的两根上,比如说:1号线接1 2柱,其他的线就不能接1 2柱了,当然一条线只能接2个接线柱。

题解:如果把所有的距离都放进优先队列里面,肯定会T,因为找距离就是O(n^2),所以我们考虑先把x_{i+1} -x_{i} 放到队列里面,把线的长度排序,看看最小的,与优先队列里面最小的是否匹配,如果匹配,pop掉,假设pop的两个的位置是i,j那么再往队列里面加x_{j+1}-x_{i}x_{j}-x_{i-1},如果不匹配直接输出“no”,因为不会有更小的距离了。注意标记两个接线柱之间只能用一次。

注意:可能是我的写法问题,用long long会超内存,改成int,用map标记会T,改成unordered_map标记

上代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <tr1/unordered_map>
using namespace std;
using namespace tr1;
const int MAX = 5e5+100;
struct hh{
	int l,r,w;
	bool operator < (const hh& b) const
	{
		return w>b.w;
	}
}tmp;
priority_queue<hh> q;
int b[MAX];
int c[MAX];
unordered_map<int,unordered_map<int,int> > mp;
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for (int i = 0; i < n;i++){
		scanf("%d",&c[i]);
	}
	for (int i = 0; i < m;i++){
		scanf("%d",&b[i]);
	}
	for (int i = 0; i < n-1;i++){
		tmp.l=i;
		tmp.r=i+1;
		tmp.w=c[i+1]-c[i];
		q.push(tmp);
	}
	sort(b,b+m);
	int cnt=0;
	while(!q.empty()){
		hh fuck=q.top();
		q.pop();
		//cout << fuck.w << " " << fuck.l << " " << fuck.r  << endl;
		if(b[cnt]>=fuck.w){
			cnt++;
			int l=fuck.l;
			int r=fuck.r;
			tmp.l=l-1;
			tmp.r=r;
			if(tmp.l>=0&&mp[tmp.l][tmp.r]==0){
				mp[tmp.l][tmp.r]=1;
				tmp.w=c[tmp.r]-c[tmp.l];
				q.push(tmp);
			//	cout << tmp.w << " " << tmp.l << " " << tmp.r << "*" << endl;
			}
			tmp.l=l;
			tmp.r=r+1;
			if(tmp.r<n&&mp[tmp.l][tmp.r]==0){
				mp[tmp.l][tmp.r]=1;
				tmp.w=c[tmp.r]-c[tmp.l];
				q.push(tmp);
				//cout << tmp.w << " " << tmp.l << " " << tmp.r << "&" << endl;
			}
		}
		else{
			if(cnt<m){
				puts("no");
				return 0;
			}
		}
		if(cnt==m) break;
	}
	if(cnt==m) puts("yes");
	else puts("no");
	return 0;
} 
发布了195 篇原创文章 · 获赞 27 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lgz0921/article/details/100108251