UVa11134 Fabled Rooks

                                  Problem F: Fabled Rooks

We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the following restrictions

  • The i-th rook can only be placed within the rectangle given by its left-upper corner (xliyli) and its right-lower corner (xriyri), where 1 ≤ i ≤ n, 1 ≤ xli ≤ xri ≤ n, 1 ≤ yli ≤ yri ≤ n.
  • No two rooks can attack each other, that is no two rooks can occupy the same column or the same row.

The input consists of several test cases. The first line of each of them contains one integer number, n, the side of the board. n lines follow giving the rectangles where the rooks can be placed as described above. The i-th line among them gives xliylixri, and yri. The input file is terminated with the integer `0' on a line by itself.

Your task is to find such a placing of rooks that the above conditions are satisfied and then output n lines each giving the position of a rook in order in which their rectangles appeared in the input. If there are multiple solutions, any one will do. Output IMPOSSIBLE if there is no such placing of the rooks.

Sample input

8
1 1 2 2
5 7 8 8
2 2 5 5
2 2 5 5
6 3 8 6
6 3 8 5
6 3 8 8
3 6 7 8
8
1 1 2 2
5 7 8 8
2 2 5 5
2 2 5 5
6 3 8 6
6 3 8 5
6 3 8 8
3 6 7 8
0

Output for sample input

1 1
5 8
2 4
4 2
7 3
8 5
6 6
3 7
1 1
5 8
2 4
4 2
7 3
8 5
6 6
3 7

K. Diks, adapted by P. Rudnicki

题目大意:有N个车,要求你置放在N*N的棋盘山,使得任意两辆车不互相攻击,如果两辆车在同一行或者同一列那么将互相攻击。题目给出了每个车的横坐标和纵坐标的范围。

题解:刚看上去果断很像N皇后问题,但是这个里的N<=5000!!!如果用DFS会无限超时啊。。。不过我们可以发现,此题少了个约束条件,不要求两个车不能同时在对角线上。并且还给出了每个车的放置范围。这样我们可以用贪心来做此题。行和列是相互独立的,在确定车的行号的时候,对车的列号没有任何影响。我们可以先确定每个行号对应的的车,每次我们都选择xli<=行号,并且xri最小的那个车,为什么呢?假设xl1==xl2,xr1<xr2,显然第二辆车选择行号的范围更大,第一辆车选择的余地更小,因此我们选择先放置第一辆车,这样得到的结果肯定不会比选择放置第二辆车得到的结果差。对于每辆车的列号运用同样的贪心方法去做。

View Code
 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #define MAXN 5005
 5 typedef struct
 6 {
 7     long xl,yl,xr,yr,col,row;
 8 } NODE;
 9 NODE s[MAXN];
10 long order[MAXN];
11 long n;
12 int main(void)
13 {
14     long i,j,flag;
15     while(scanf("%ld",&n)!=EOF)
16     {
17         if(n==0) break;
18         memset(s,0,sizeof(s));
19         for(i=0; i<n; i++)
20             scanf("%ld%ld%ld%ld",&s[i].xl,&s[i].yl,&s[i].xr,&s[i].yr);
21         long dd=1,maxs,dr,f[MAXN];
22         flag=1;
23         memset(f,0,sizeof(f));
24         for(i=0; i<n; i++)
25         {
26             maxs=MAXN;
27             for(j=0;j<n;j++)
28             if(s[j].xl<=dd&&s[j].xr>=dd&&s[j].xr<maxs&&!f[j])
29             {
30                maxs=s[j].xr;
31                dr=j;
32             }
33             if(maxs==MAXN)
34             {
35                 flag=0;
36                 break;
37             }
38             s[dr].col=dd;
39             f[dr]=1;
40             dd++;
41         }
42         if(flag)
43         {
44             long dd=1,maxs,dr,f[MAXN];
45             memset(f,0,sizeof(f));
46             for(i=0; i<n; i++)
47             {
48                 maxs=MAXN;
49                 for(j=0;j<n;j++)
50                 if(s[j].yl<=dd&&s[j].yr>=dd&&s[j].yr<maxs&&!f[j])
51                 {
52                     maxs=s[j].yr;
53                     dr=j;
54                 }
55                 if(maxs==MAXN)
56                 {
57                     flag=0;
58                     break;
59                 }
60                 s[dr].row=dd;
61                 f[dr]=1;
62                 dd++;
63             }
64         }
65         if(flag)
66         {
67             for(i=0; i<n; i++)
68                 printf("%ld %ld\n",s[i].col,s[i].row);
69         }
70         else
71             printf("IMPOSSIBLE\n");
72     }
73     return 0;
74 }
原文地址:https://www.cnblogs.com/zjbztianya/p/2983126.html