【POJ】1084 Square Destroyer

1. 题目描述
由$n \times n, n \in [1, 5]$的正方形由$2 \times n \times (n+1)$根木棍组成,可能已经有些木棍被破坏,求至少还需破坏多少木根,可以使得不存在任何正方形?

2. 基本思路
这是一道非常有趣的题目,可以使用IDA*解也可以用DLX解。可以试试5 0这组数据比较两者的性能差异。
(1) IDA*
使用IDA*处理,是因为最后的解的范围一定不是很大,因为数据很小。至多也就60根木棍。
首先可以预处理分别对正方形和木棍进行编号,进而预处理破坏每根木棍可以影响的正方形。
由于木棍和正方形都不超过60个,因此可以采用longlong进行状态压缩,一定要装压,否则就哭吧。
每次选择当前仍然存在的最小正方形,然后枚举它的每条边进行深搜。

(2) DLX
使用DLX解这道题很容易理解, 而且解5 0这组数据也很快。
首先仍然可以使用上述的预处理方法。从而可以得到当前木棍中仍然存在的正方形。
如果,当前不存在正方形则直接输出0。否则以正方形的个数初始化DLX。
接下来,枚举每条边,搜索它可以影响到的正方形,建立一个可行方案。
直接套用DLX可解,注意DLX加入H函数可以加速,而且效果还是挺明显的。

3. 代码
(1)IDA*

  1 /* 1084 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 #define INF                0x3f3f3f3f
 44 #define mset(a, val)    memset(a, (val), sizeof(a))
 45
 46 #define LL long long
 47
 48 typedef struct {
 49     vector<LL> sq;
 50     int sz;
 51 } sqInfo_t;
 52
 53
 54 const int maxm = 65;
 55 int rowId[6][6];
 56 int colId[6][6];
 57 int n, tot;
 58 LL st;
 59 sqInfo_t sqInfo[6];
 60
 61 void init_sq(int n) {
 62     int cnt = 0;
 63     sqInfo_t& info = sqInfo[n];
 64     vector<LL>& sq = info.sq;
 65     int& sz = info.sz;
 66
 67     rep(i, 0, n) {
 68         rep(j, 0, n)
 69             rowId[i][j] = cnt++;
 70         rep(j, 0, n+1)
 71             colId[i][j] = cnt++;
 72     }
 73     rep(j, 0, n)
 74         rowId[n][j] = cnt++;
 75
 76     cnt = 0;
 77     rep(i, 0, n) {
 78         rep(j, 0, n) {
 79             rep(k, 1, n+1) {
 80                 if (i+k>n || j+k>n)
 81                     break;
 82
 83                 LL val = 0;
 84
 85                 // Top
 86                 rep(l, 0, k) {
 87                     val |= (1LL << rowId[i][j+l]);
 88                 }
 89
 90                 // Left
 91                 rep(l, 0, k) {
 92                     val |= (1LL << colId[i+l][j]);
 93                 }
 94
 95                 // Down
 96                 rep(l, 0, k) {
 97                     val |= (1LL << rowId[i+k][j+l]);
 98                 }
 99
100                 // Right
101                 rep(l, 0, k) {
102                     val |= (1LL << colId[i+l][j+k]);
103                 }
104
105                 sq.pb(val);
106                 ++sz;
107             }
108         }
109     }
110 }
111
112 void init() {
113     rep(i, 1, 6)
114         init_sq(i);
115 }
116
117
118 bool dfs(int m, LL cst) {
119     const int& sz = sqInfo[n].sz;
120     const vector<LL>& sq = sqInfo[n].sq;
121     int h = 0;
122     LL st = -1, tmp = cst;
123
124     rep(i, 0, sz) {
125         if ((tmp & sq[i]) == sq[i]) {
126             ++h;
127             tmp ^= sq[i];
128             if (st < 0)
129                 st = sq[i];
130         }
131     }
132
133     if(h == 0)
134         return true;
135
136     if (m < h)
137         return false;
138
139     rep(i, 0, tot) {
140         if (st & (1LL << i)) {
141             if ( dfs(m-1, cst^(1LL<<i)) )    return true;
142         }
143     }
144     return false;
145 }
146
147 void solve() {
148     int ans = -1;
149
150     for (int i=0; i<=tot; ++i) {
151         if (dfs(i, st)) {
152             ans = i;
153             break;
154         }
155     }
156
157     printf("%d\n", ans);
158 }
159
160 int main() {
161     ios::sync_with_stdio(false);
162     #ifndef ONLINE_JUDGE
163         freopen("data.in", "r", stdin);
164         freopen("data.out", "w", stdout);
165     #endif
166
167     int t;
168
169     init();
170     scanf("%d", &t);
171     while (t--) {
172         scanf("%d", &n);
173         tot = n*(n+1)*2;
174         int k, x;
175         st = (1LL << tot) - 1;
176
177         scanf("%d", &k);
178         while (k--) {
179             scanf("%d", &x);
180             --x;
181             st ^= (1LL << x);
182         }
183         solve();
184     }
185
186     #ifndef ONLINE_JUDGE
187         printf("time = %d.\n", (int)clock());
188     #endif
189
190     return 0;
191 }

(2)Dancing Links

  1 /* 1084 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 #define INF                0x3f3f3f3f
 44 #define mset(a, val)    memset(a, (val), sizeof(a))
 45
 46 #define LL __int64
 47
 48 typedef struct {
 49     static const int maxr = 65;
 50     static const int maxc = 65;
 51     static const int maxn = maxr * maxc;
 52
 53     int n, sz;
 54     int S[maxc];
 55     bool visit[maxc];
 56
 57     int col[maxn];
 58     int L[maxn], R[maxn], U[maxn], D[maxn];
 59
 60     int ansd;
 61
 62     void init(int _n) {
 63         n = _n;
 64
 65         rep(i, 0, n+1) {
 66             L[i] = i - 1;
 67             R[i] = i + 1;
 68             U[i] = i;
 69             D[i] = i;
 70             col[i] = i;
 71         }
 72
 73         L[0] = n;
 74         R[n] = 0;
 75
 76         sz = n + 1;
 77         memset(S, 0, sizeof(S));
 78         ansd = INF;
 79     }
 80
 81     void addRow(const vi& columns) {
 82         int first = sz;
 83         int size = SZ(columns);
 84
 85         rep(i, 0, size) {
 86             const int& c = columns[i];
 87
 88             L[sz] = sz - 1;
 89             R[sz] = sz + 1;
 90
 91             D[sz] = c;
 92             U[sz] = U[c];
 93             D[U[c]] = sz;
 94             U[c] = sz;
 95
 96             col[sz] = c;
 97
 98             ++S[c];
 99             ++sz;
100         }
101
102         L[first] = sz - 1;
103         R[sz-1] = first;
104     }
105
106     void remove_col(int c) {
107         for (int i=D[c]; i!=c; i=D[i]) {
108             L[R[i]] = L[i];
109             R[L[i]] = R[i];
110             --S[col[i]];
111         }
112     }
113
114     void restore_col(int c) {
115         for (int i=D[c]; i!=c; i=D[i]) {
116             L[R[i]] = i;
117             R[L[i]] = i;
118             ++S[col[i]];
119         }
120     }
121
122     int H() {
123         int ret = 0;
124
125         memset(visit, false, sizeof(visit));
126         for (int i=R[0]; i; i=R[i]) {
127             if (visit[col[i]])
128                 continue;
129
130             ++ret;
131             visit[col[i]] = true;
132             for (int j=D[i]; j!=i; j=D[j]) {
133                 for (int k=R[j]; k!=j; k=R[k]) {
134                     visit[col[k]] = true;
135                 }
136             }
137         }
138
139         return ret;
140     }
141
142     void dfs(int d) {
143         int delta = H();
144
145         if (d+delta >= ansd)
146             return ;
147
148         if (R[0] == 0) {
149             ansd = d;
150             return ;
151         }
152
153         int c = R[0];
154         for (int i=R[0]; i; i=R[i]) {
155             if (S[i] < S[c])
156                 c = i;
157         }
158
159         for (int i=D[c]; i!=c; i=D[i]) {
160             remove_col(i);
161             for (int j=R[i]; j!=i; j=R[j]) {
162                 remove_col(j);
163             }
164             dfs(d + 1);
165             for (int j=L[i]; j!=i; j=L[j]) {
166                 restore_col(j);
167             }
168             restore_col(i);
169         }
170     }
171
172 } DLX;
173
174 typedef struct {
175     vector<LL> sq;
176     int sz;
177 } sqInfo_t;
178
179 DLX solver;
180 const int maxm = 65;
181 bool mark[maxm];
182 int valid[maxm];
183 int rowId[6][6];
184 int colId[6][6];
185 int n, tot;
186 LL st;
187 sqInfo_t sqInfo[6];
188
189 void init_sq(int n) {
190     int cnt = 0;
191     sqInfo_t& info = sqInfo[n];
192     vector<LL>& sq = info.sq;
193     int& sz = info.sz;
194
195     rep(i, 0, n) {
196         rep(j, 0, n)
197             rowId[i][j] = cnt++;
198         rep(j, 0, n+1)
199             colId[i][j] = cnt++;
200     }
201     rep(j, 0, n)
202         rowId[n][j] = cnt++;
203
204     cnt = 0;
205     rep(i, 0, n) {
206         rep(j, 0, n) {
207             rep(k, 1, n+1) {
208                 if (i+k>n || j+k>n)
209                     break;
210
211                 LL val = 0;
212
213                 // Top
214                 rep(l, 0, k) {
215                     val |= (1LL << rowId[i][j+l]);
216                 }
217
218                 // Left
219                 rep(l, 0, k) {
220                     val |= (1LL << colId[i+l][j]);
221                 }
222
223                 // Down
224                 rep(l, 0, k) {
225                     val |= (1LL << rowId[i+k][j+l]);
226                 }
227
228                 // Right
229                 rep(l, 0, k) {
230                     val |= (1LL << colId[i+l][j+k]);
231                 }
232
233                 sq.pb(val);
234                 ++sz;
235             }
236         }
237     }
238 }
239
240 void init() {
241     rep(i, 1, 6)
242         init_sq(i);
243 }
244
245 void solve() {
246     const vector<LL>& sq = sqInfo[n].sq;
247     const int& sz = sqInfo[n].sz;
248     int m = 0;
249
250     rep(i, 0, sz) {
251         if ((st & sq[i]) == sq[i]) {
252             valid[m++] = i;
253         }
254     }
255
256     if (m == 0) {
257         puts("0");
258         return ;
259     }
260
261     solver.init(m);
262
263     rep(i, 0, tot) {
264         if (mark[i]) {
265             vi vc;
266
267             rep(j, 0, m) {
268                 if (sq[valid[j]] & (1LL << i))
269                     vc.pb(j+1);
270             }
271
272             if (SZ(vc) > 0) {
273                 solver.addRow(vc);
274             }
275         }
276     }
277
278     solver.dfs(0);
279     int ans = solver.ansd;
280
281     printf("%d\n", ans);
282 }
283
284 int main() {
285     ios::sync_with_stdio(false);
286     #ifndef ONLINE_JUDGE
287         freopen("data.in", "r", stdin);
288         freopen("data.out", "w", stdout);
289     #endif
290
291     int t;
292
293     init();
294     scanf("%d", &t);
295     while (t--) {
296         scanf("%d", &n);
297         memset(mark, true, sizeof(mark));
298         tot = n*(n+1)*2;
299         int k, x;
300         st = (1LL << tot) - 1;
301
302         scanf("%d", &k);
303         while (k--) {
304             scanf("%d", &x);
305             mark[--x] = false;
306             st ^= (1LL << x);
307         }
308         solve();
309     }
310
311     #ifndef ONLINE_JUDGE
312         printf("time = %d.\n", (int)clock());
313     #endif
314
315     return 0;
316 }

4. 数据生成器

 1 import sys
 2 import string
 3 from random import randint, shuffle
 4
 5
 6 def GenData(fileName):
 7     with open(fileName, "w") as fout:
 8         t = 20
 9         fout.write("%d\n" % (t))
10         for tt in xrange(t):
11             n = randint(1, 5)
12             tot = n * (n + 1)
13             taken = randint(1, tot)
14             L = range(1, tot+1)
15             shuffle(L)
16             fout.write("%d %d\n" % (n, taken))
17             fout.write(" ".join(map(str, L[:taken])) + "\n")
18
19
20 def MovData(srcFileName, desFileName):
21     with open(srcFileName, "r") as fin:
22         lines = fin.readlines()
23     with open(desFileName, "w") as fout:
24         fout.write("".join(lines))
25
26
27 def CompData():
28     print "comp"
29     srcFileName = "F:\Qt_prj\hdoj\data.out"
30     desFileName = "F:\workspace\cpp_hdoj\data.out"
31     srcLines = []
32     desLines = []
33     with open(srcFileName, "r") as fin:
34         srcLines = fin.readlines()
35     with open(desFileName, "r") as fin:
36         desLines = fin.readlines()
37     n = min(len(srcLines), len(desLines))-1
38     for i in xrange(n):
39         ans2 = int(desLines[i])
40         ans1 = int(srcLines[i])
41         if ans1 > ans2:
42             print "%d: wrong" % i
43
44
45 if __name__ == "__main__":
46     srcFileName = "F:\Qt_prj\hdoj\data.in"
47     desFileName = "F:\workspace\cpp_hdoj\data.in"
48     GenData(srcFileName)
49     MovData(srcFileName, desFileName)

时间: 2024-10-03 20:42:40

【POJ】1084 Square Destroyer的相关文章

【POJ】3009 Curling 2.0 ——DFS

Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11432   Accepted: 4831 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is

【POJ】2278 DNA Sequence

各种wa后,各种TLE.注意若AC非法,则ACT等一定非法.而且尽量少MOD. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 105 8 #define NXTN 4 9 10 char str[15]; 11 12 typedef struct Matrix {

【POJ】1739 Tony&#39;s Tour

http://poj.org/problem?id=1739 题意:n×m的棋盘,'#'是障碍,'.'是空白,求左下角走到右下角且走过所有空白格子的方案数.(n,m<=8) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; #define BIT(a,b) ((a)<<((b)<<1)) #

【POJ】2449 Remmarguts&#39; Date(k短路)

http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k 首先我们建反向边,跑一次从汇到源的最短路,将跑出来的最短路作为估价函数h 根据f=g+h 我们将源s先走,此时实际价值g为0,估价为最短路(他们的和就是s-t的最短路) 将所有s所连的边都做相同的处理,加入到堆中(假设此时到达的点为x,那么x的g等于s到这个点的边权,因为根据最优,g+h此时是从x

【POJ】2318 TOYS ——计算几何+二分

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

【POJ】1056 IMMEDIATE DECODABILITY

字典树水题. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 typedef struct Trie { 6 bool v; 7 Trie *next[2]; 8 } Trie; 9 10 Trie *root; 11 12 bool create(char str[]) { 13 int i = 0, id; 14 bool ret = false; 15 Trie *p = root

【POJ】2418 Hardwood Species

简单字典树. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXN 128 6 7 typedef struct Trie { 8 int count; 9 Trie *next[MAXN]; 10 Trie() { 11 count = 0; 12 for (int i=0; i<MAXN; ++i) 13 next[i] = NULL; 14 } 15 }

【POJ】2513 Colored Sticks

字典树+并查集. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXN 500005 6 #define MAXL 11 7 #define TRIEN 26 8 9 typedef struct Trie { 10 int v; 11 Trie *next[TRIEN]; 12 Trie() { 13 v = 0; 14 for (int i=0; i<TRI

【POJ】 2528 - Mayor&#39;s posters 【线段树+离散化】

题目: Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 47228   Accepted: 13719 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral