您的位置:首页 > 其它

CF 556D Case of Fugitive 根据岛屿选择桥(贪心)

2015-06-29 20:52 260 查看
http://codeforces.com/contest/556/problem/D

题意:给你n个岛屿 m个桥,岛屿在一条线上

给岛屿的左坐标与又坐标(L,R).从左到右按顺序给每个岛的L,R

再给你每个桥的长度,每个桥只能用一次

让你用桥把岛屿连接起来,能连则输出yes,并且输出每两个岛屿之间的桥的编号

连接的要求是,每个桥要能连接两个相邻岛屿,又不能越出两个岛屿的最大距离,即x>=L[i+1]-R[i] && x<=R[i+1]-L[i]

思路:贪心,存下两两相邻岛屿之间的最大距离max,最小距离min,进行排序,先是max从小到大,max相同则min从小到大

在所有的桥里面找,先满足最小max的对应的min,如果找不到或者找到的桥比max打,则肯定不行,否则一直往后找

#include<set>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iostream>
#define S second
#define F first
using namespace std;
const int MAX = 200005;
typedef long long LL;
LL xx;
set< pair<LL,int> >bridge; //桥的集合
pair< pair<LL,LL>,int >island[MAX]; //先表示岛屿,以后会表示相邻岛屿之间的属性
int ans[MAX];
int main()
{
int n,m,i;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%I64d%I64d",&island[i].F.F,&island[i].F.S); //对于岛屿目前只需要 L R 的属性
for(i=1;i<=m;i++){
scanf("%I64d",&xx);
bridge.insert(make_pair(xx,i));
}
for(i=0;i<n-1;i++){ //“两两相邻”只有n-1个
LL i_min=island[i+1].F.F-island[i].F.S;
LL i_max=island[i+1].F.S-island[i].F.F;
island[i].S=i;
island[i].F.F=i_max;island[i].F.S=i_min; //“两两相邻”的属性,max,min,编号i
}
sort(island,island+n-1);
for(i=0;i<n-1;i++){
set<pair<LL,int> >::iterator it;
it=bridge.lower_bound(make_pair(island[i].F.S,0)); //找桥
if( it==bridge.end() || (it->F)>island[i].F.F ) break;//桥没找到 或者 桥比最大值大,则不合格
ans[island[i].S]=it->S; //存下桥的编号
bridge.erase(it);//删除此桥
}
if(i==n-1){
puts("Yes");
for(i=0;i<n-2;i++) printf("%d ",ans[i]);
printf("%d\n",ans[i]);
}
else puts("No");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: