ZOJ 3209 Treasure Map (Dancing Links)

Treasure Map
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu
Appoint description: 

Description

Your boss once had got many copies of a treasure map. Unfortunately, all the copies are now broken to many rectangular pieces, and what make it worse, he has lost some of the pieces. Luckily, it is possible to figure out the position of each piece in the original map. Now the boss asks you, the talent programmer, to make a complete treasure map with these pieces. You need to make only one complete map and it is not necessary to use all the pieces. But remember, pieces are not allowed to overlap with each other (See sample 2).

 

Input

 

The first line of the input contains an integer T (T <= 500), indicating the number of cases.

For each case, the first line contains three integers nmp (1 <= nm <= 30, 1 <= p <= 500), the width and the height of the map, and the number of pieces. Then p lines follow, each consists of four integers x1y1x2y2 (0 <= x1 < x2 <= n, 0 <= y1 < y2 <= m), where (x1, y1) is the coordinate of the lower-left corner of the rectangular piece, and (x2, y2) is the coordinate of the upper-right corner in the original map.

Cases are separated by one blank line.

 

 

Output

 

If you can make a complete map with these pieces, output the least number of pieces you need to achieve this. If it is impossible to make one complete map, just output -1.

 

Sample Input

 

3
5 5 1
0 0 5 5

5 5 2
0 0 3 5
2 0 5 5

30 30 5
0 0 30 10
0 10 30 20
0 20 30 30
0 0 15 30
15 0 30 30

 

Sample Output

 

1
-1
2

Hint

For sample 1, the only piece is a complete map.

For sample 2, the two pieces may overlap with each other, so you can not make a complete treasure map.

For sample 3, you can make a map by either use the first 3 pieces or the last 2 pieces, and the latter approach one needs less pieces.

 

 

 

 

草泥马啊!!!!N和M弄反了啊!!!!!T了一下午啊!!!!!!!!找BUG都快找哭了啊!!!!!!!!!!

丧心病狂弄了个M行N列啊!!!!!!!!!!这尼玛反人类啊!!!!!!活生生由300ms优化到了80ms啊!!!!!!!!!

  1 #include <iostream>
  2 #include <cstdio>
  3 using    namespace    std;
  4 
  5 const    int    SIZE = 1005 * 505;
  6 const    int    HEAD = 0;
  7 int    U[SIZE],D[SIZE],L[SIZE],R[SIZE],C[SIZE],S[SIZE];
  8 int    N,M;
  9 int    ANS = 0x7fffffff;
 10 
 11 void    ini(void);
 12 void    dancing(int ans);
 13 void    remove(int);
 14 void    resume(int);
 15 int    main(void)
 16 {
 17     int    t,p,count;
 18     int    x_1,y_1,x_2,y_2;
 19     int    col;
 20 
 21     scanf("%d",&t);
 22     while(t --)
 23     {
 24         ANS = 0x7fffffff;
 25         scanf("%d%d%d",&N,&M,&p);
 26         ini();
 27         count = N * M + 1;
 28         while(p --)
 29         {
 30             scanf("%d%d%d%d",&x_1,&y_1,&x_2,&y_2);
 31 
 32             int    first = count;
 33             for(int i = x_1;i < x_2;i ++)
 34                 for(int j = y_1;j < y_2;j ++)
 35                 {
 36                     col = i * M + j + 1;
 37                     U[count] = U[col];
 38                     D[count] = col;
 39                     L[count] = count - 1;
 40                     R[count] = count + 1;
 41 
 42                     D[U[col]] = count;
 43                     U[col] = count;
 44 
 45                     C[count] = col;
 46                     ++ S[col];
 47                     ++ count;
 48                 }
 49             R[count - 1] = first;
 50             L[first] = count - 1;
 51         }
 52         dancing(0);
 53         if(ANS == 0x7fffffff)
 54             puts("-1");
 55         else
 56             printf("%d\n",ANS);
 57     }
 58 
 59     return    0;
 60 }
 61 
 62 void    ini(void)
 63 {
 64     L[HEAD] = N * M;
 65     R[HEAD] = 1;
 66     U[HEAD] = D[HEAD] = S[HEAD] = C[HEAD] = HEAD;
 67 
 68     for(int i = 1;i <= N * M;i ++)
 69     {
 70         U[i] = D[i] = i;
 71         L[i] = i - 1;
 72         R[i] = i + 1;
 73 
 74         C[i] = i;
 75         S[i] = 0;
 76     }
 77     R[N * M] = 0;
 78 }
 79 
 80 void    dancing(int ans)
 81 {
 82     if(ans >= ANS)
 83         return    ;
 84 
 85     if(R[HEAD] == HEAD)
 86     {
 87         ANS = ans < ANS ? ans : ANS;
 88         return    ;
 89     }
 90 
 91     int    min_loc = R[HEAD];
 92     for(int i = R[HEAD];i;i = R[i])
 93         if(S[i] < S[min_loc])
 94             min_loc = i;
 95 
 96     remove(min_loc);
 97     for(int i = D[min_loc];i != min_loc;i = D[i])
 98     {
 99         for(int j = R[i];j != i;j = R[j])
100             remove(C[j]);
101         dancing(ans + 1);
102         for(int j = L[i];j != i;j = L[j])
103             resume(C[j]);
104     }
105     resume(min_loc);
106 
107 }
108 
109 void    remove(int c)
110 {
111     R[L[c]] = R[c];
112     L[R[c]] = L[c];
113 
114     for(int i = D[c];i != c;i = D[i])
115         for(int j = R[i];j != i;j = R[j])
116         {
117             D[U[j]] = D[j];
118             U[D[j]] = U[j];
119             -- S[C[j]];
120         }
121 }
122 
123 void    resume(int c)
124 {
125     R[L[c]] = c;
126     L[R[c]] = c;
127 
128     for(int i = U[c];i != c;i = U[i])
129         for(int j = R[i];j != i;j = R[j])
130         {
131             D[U[j]] = j;
132             U[D[j]] = j;
133             ++ S[C[j]];
134         }
135 }

 

posted @ 2015-04-09 17:15  Decouple  阅读(545)  评论(0编辑  收藏  举报