题意:你的任务是在n*n的棋盘上放n辆车,使得任意两辆车不相互攻击,且第i辆车要在一个给定的矩形Ri之内
思路:首先明确的是对于每一辆车它所在的行和列是不互相影响的,那么分别讨论每一辆车的行和列,像八皇后问题一样讨论没一行或列放什么,对于一辆车来说贪心的将它放在尽可能靠前的位置显然不会是更差的
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 5010; struct node{ int x1,x2,x3,y1,y2,y3,id; }arr[MAXN]; int n,vis[MAXN]; bool cmp1(node a,node b){ if(a.x1==b.x1) return a.x2<b.x2; return a.x1<b.x1; } bool cmp2(node a,node b){ if(a.y1==b.y1) return a.y2<b.y2; return a.y1<b.y1; } bool cmp3(node a,node b){ return a.id < b.id; } int main(){ while (scanf("%d",&n) != EOF && n){ int flag = 1; for (int i = 1; i <= n; i++){ scanf("%d%d%d%d",&arr[i].x1,&arr[i].y1,&arr[i].x2,&arr[i].y2); arr[i].id = i; } sort(arr+1,arr+1+n,cmp1); memset(vis,0,sizeof(vis)); for (int i = 1; i <= n; i++){ int cnt = -1,x = MAXN; for (int j = 1; j <= n; j++){ if (arr[j].x1 > i) break; else if (arr[j].x2 < x && arr[j].x2 >= i && !vis[j]){ cnt = j; x = arr[j].x2; } } if (cnt == -1){ flag = 0; break; } vis[cnt] = 1; arr[cnt].x3 = i; } if (flag == 0){ printf("IMPOSSIBLE\n"); continue; } sort(arr+1,arr+1+n,cmp2); memset(vis,0,sizeof(vis)); for (int i = 1; i <= n; i++){ int cnt = -1,x = MAXN; for (int j = 1; j <= n; j++){ if (arr[j].y1 > i) break; else if (arr[j].y2 < x && arr[j].y2 >= i && !vis[j]){ cnt = j; x = arr[j].y2; } } if (cnt == -1){ flag = 0; break; } vis[cnt] = 1; arr[cnt].y3 = i; } if (!flag){ printf("IMPOSSIBLE\n"); continue; } sort(arr+1,arr+1+n,cmp3); for (int i = 1; i <= n; i++) printf("%d %d\n",arr[i].x3,arr[i].y3); } return 0; }