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;
} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心脏dance

如果解决了您的疑惑,谢谢打赏呦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值