2017辽宁冬令营-4.蚂蚁
蚂蚁(ant.pas/c/cpp)
题目大意
在平面上有 N 只蚂蚁 N 个树洞,每个树洞只能容纳下一只蚂蚁,蚂蚁们都是直线行走
的。 现在蚂蚁们希望能进入树洞中, 希望你能构造出一种方案使得任意两个蚂蚁的路线不相
交。
保证不会出现三点共线的情况。对于有多种不同的解,输出任意一组即可。无解时,输
出-1。
输入文件
输入文件为 ant.in。
第一行为一个数 N。
接下来 N 行,每行两个非负整数,第 i+1 行为第 i 号蚂蚁的坐标。
接下来 N 行,每行两个非负整数,第 i+N+1 行为第 i 号树洞的坐标。
输出文件
输出文件为 ant.out。
共 N 行,每行一个数,为第 i 号蚂蚁进入的树洞编号,若无解仅需输出一行一个数-1。
样例输入
5
10 8
5 3
4 8
5 4
8 4
7 9
7 6
2 5
8 5
1 6
样例输出
1
3
2
5
4
数据规模与约定
对于 30%的数据,N≤20;
对于 70%的数据,N≤200;
对于 100%的数据,N≤1000。
————————————————————————————题解
我们选择一个最左下角的点,然后把其他的点按照它们与这个点的极角排序,我们一定可以找到一条最左下点和它的一个对应点把平面分割成两个部分,每个平面里面树洞个数和蚂蚁个数相等,然后我们可以递归处理
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring>//important 4 #include <algorithm> 5 #define siji(i,x,y) for(int i=(x);i<=(y);++i) 6 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j) 7 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i) 8 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j) 9 #define ivorysi 10 typedef long long ll; 11 using namespace std; 12 int n; 13 struct vec { 14 int x,y,id,ok; 15 ll operator *(const vec &a) const{ 16 return (ll)x*a.y-(ll)y*a.x; 17 } 18 bool operator < (const vec &a)const{ 19 return x==a.x ? y<a.y : x<a.x; 20 } 21 vec operator - (const vec &a) const { 22 vec c;c.x=x-a.x;c.y=y-a.y; 23 return c; 24 } 25 }pos[2005]; 26 int hole[2005]; 27 int cross(vec a,vec b){ 28 return a.x*b.y-a.y*b.x; 29 } 30 31 void init() { 32 scanf("%d",&n); 33 siji(i,1,n) { 34 scanf("%d%d",&pos[i].x,&pos[i].y); 35 pos[i].ok=1;pos[i].id=i; 36 } 37 siji(i,n+1,2*n) { 38 scanf("%d%d",&pos[i].x,&pos[i].y); 39 pos[i].ok=-1;pos[i].id=i; 40 } 41 } 42 vec st; 43 bool cmp(vec c,vec d) { 44 return (c-st)*(d-st)>0; 45 } 46 void solve(int c,int d) { 47 if(c+1>d) return; 48 sort(pos+c,pos+1+d);//对于每个区间重新按最靠左下排序 49 st=pos[c]; 50 sort(pos+c+1,pos+1+d,cmp);//极角排序 51 52 int t=pos[c].ok; 53 int divnum; 54 siji(i,c+1,d) { 55 t+=pos[i].ok; 56 if(t==0) {divnum=i;break;} 57 } 58 hole[pos[c].id]=pos[divnum].id; 59 hole[pos[divnum].id]=pos[c].id; 60 solve(c+1,divnum-1); 61 solve(divnum+1,d); 62 } 63 int main(int argc, char const *argv[]) 64 { 65 #ifdef ivorysi 66 freopen("ant.in","r",stdin); 67 freopen("ant.out","w",stdout); 68 #else 69 freopen("f1.in","r",stdin); 70 #endif 71 init(); 72 solve(1,2*n); 73 siji(i,1,n) { 74 printf("%d\n",hole[i]-n); 75 } 76 return 0; 77 }