MD,又因为一个傻逼错误搞了一个下午+一个晚上。。忧桑= =
题意:
现在有n个点,然后给出n个点的x,y坐标。然后这些坐标必须满足条件:比如说分配给点(x,y)的标号是i,那么点(x',y')的标号就必须是大于i的(这里x'>=x 或者 y'>=y 或者 x'>=x&&y'>=y)
然后给你n个的权值w[i],并且告诉你n个点的权值的计算公式是: s(xi, yi) = yi - xi = wi
然后让你安排n个点的标号,使它们在同时满足标号原则的前提下,并且使得第i个点的权值刚好满足w[i]。
思路:
比赛的时候没想到怎么给它们分配标号,参考了题解,很简单啊,首先先给它们进行排序,先按x值从小到大排,若x值相等,那么就按照y值从小到大排。然后,就是把权值为w[i]的点的坐标全都存下来,再来分配就好啦。
然后,判断是否符合标号原则,我们记arr[i][j]为权值为i的点集合中第j个点的序号,然后让它去与arr[i+1][j]和arr[i][j+1]去判断就好了。这里注意要判断arr[i+1],arr[j+1]这个集合是否为空,如果为空的那么这个点就不要判断了。
这题可能w[i]为负,所以我的办法是把它们全都进行平移10000个单位,相当于移动了坐标系。
噢,这题还有许多关于STL的用法,STL用的好的话真是十分方便的呢。还有pair函数,哈哈,第一次用呢。
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
typedef __int64 ll;
typedef unsigned __int64 ULL;
#define inf 99999999
#define add 100000
#define maxn 200022
int w[maxn];
struct node{
int x,y;
int idx;
node(){}
node(int xx,int yy){
x=xx;
y=yy;
}
friend bool operator <(node a,node b){
if(a.x!=b.x) return a.x<b.x;
else return a.y<b.y;
}
};
map<int,int> mp;
set<node> st[maxn];
set<node>::iterator it;
vector<int> dian[maxn];
vector<int> ans[maxn];
pair<int,int> par[maxn];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&x,&y);
st[y-x+add].insert(node(x,y));
}
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
dian[w[i]+add].push_back(i);
}
for(int i=1;i<=n;i++){
if(st[w[i]+add].size()!=dian[w[i]+add].size()){
printf("NO\n");
return 0;
}
}
node tmp;
for(int i=1;i<=n;i++){
it=st[w[i]+add].begin();
tmp=*it;
int xx=(*it).x,yy=(*it).y;
int idx=dian[w[i]+add][mp[w[i]+add]];
par[idx]=make_pair(xx,yy);
ans[xx].push_back(yy);
int len=ans[xx].size()-1;
ans[xx][len]=idx;
st[w[i]+add].erase(tmp);
mp[w[i]+add]++;
}
for(int i=0;i<100010;i++){
for(int j=0;j<ans[i].size();j++){
if(ans[i+1].size()>j&&ans[i+1][j]<ans[i][j]){
printf("NO\n");
return 0;
}
if(j+1<ans[i].size()&&ans[i][j]>ans[i][j+1]){
printf("NO\n");
return 0;
}
}
}
printf("YES\n");
for(int i=1;i<=n;i++){
printf("%d %d\n",par[i].first,par[i].second);
}
return 0;
}
/*
9
0 0
1 0
2 0
0 1
1 1
2 1
1 2
2 2
0 2
0 0 0 -1 -1 -2 1 1 2
*/
加油!