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*

 /* 1084 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
#define INF 0x3f3f3f3f
#define mset(a, val) memset(a, (val), sizeof(a)) #define LL long long typedef struct {
vector<LL> sq;
int sz;
} sqInfo_t; const int maxm = ;
int rowId[][];
int colId[][];
int n, tot;
LL st;
sqInfo_t sqInfo[]; void init_sq(int n) {
int cnt = ;
sqInfo_t& info = sqInfo[n];
vector<LL>& sq = info.sq;
int& sz = info.sz; rep(i, , n) {
rep(j, , n)
rowId[i][j] = cnt++;
rep(j, , n+)
colId[i][j] = cnt++;
}
rep(j, , n)
rowId[n][j] = cnt++; cnt = ;
rep(i, , n) {
rep(j, , n) {
rep(k, , n+) {
if (i+k>n || j+k>n)
break; LL val = ; // Top
rep(l, , k) {
val |= (1LL << rowId[i][j+l]);
} // Left
rep(l, , k) {
val |= (1LL << colId[i+l][j]);
} // Down
rep(l, , k) {
val |= (1LL << rowId[i+k][j+l]);
} // Right
rep(l, , k) {
val |= (1LL << colId[i+l][j+k]);
} sq.pb(val);
++sz;
}
}
}
} void init() {
rep(i, , )
init_sq(i);
} bool dfs(int m, LL cst) {
const int& sz = sqInfo[n].sz;
const vector<LL>& sq = sqInfo[n].sq;
int h = ;
LL st = -, tmp = cst; rep(i, , sz) {
if ((tmp & sq[i]) == sq[i]) {
++h;
tmp ^= sq[i];
if (st < )
st = sq[i];
}
} if(h == )
return true; if (m < h)
return false; rep(i, , tot) {
if (st & (1LL << i)) {
if ( dfs(m-, cst^(1LL<<i)) ) return true;
}
}
return false;
} void solve() {
int ans = -; for (int i=; i<=tot; ++i) {
if (dfs(i, st)) {
ans = i;
break;
}
} printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; init();
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
tot = n*(n+)*;
int k, x;
st = (1LL << tot) - ; scanf("%d", &k);
while (k--) {
scanf("%d", &x);
--x;
st ^= (1LL << x);
}
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

(2)Dancing Links

 /* 1084 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
#define INF 0x3f3f3f3f
#define mset(a, val) memset(a, (val), sizeof(a)) #define LL __int64 typedef struct {
static const int maxr = ;
static const int maxc = ;
static const int maxn = maxr * maxc; int n, sz;
int S[maxc];
bool visit[maxc]; int col[maxn];
int L[maxn], R[maxn], U[maxn], D[maxn]; int ansd; void init(int _n) {
n = _n; rep(i, , n+) {
L[i] = i - ;
R[i] = i + ;
U[i] = i;
D[i] = i;
col[i] = i;
} L[] = n;
R[n] = ; sz = n + ;
memset(S, , sizeof(S));
ansd = INF;
} void addRow(const vi& columns) {
int first = sz;
int size = SZ(columns); rep(i, , size) {
const int& c = columns[i]; L[sz] = sz - ;
R[sz] = sz + ; D[sz] = c;
U[sz] = U[c];
D[U[c]] = sz;
U[c] = sz; col[sz] = c; ++S[c];
++sz;
} L[first] = sz - ;
R[sz-] = first;
} void remove_col(int c) {
for (int i=D[c]; i!=c; i=D[i]) {
L[R[i]] = L[i];
R[L[i]] = R[i];
--S[col[i]];
}
} void restore_col(int c) {
for (int i=D[c]; i!=c; i=D[i]) {
L[R[i]] = i;
R[L[i]] = i;
++S[col[i]];
}
} int H() {
int ret = ; memset(visit, false, sizeof(visit));
for (int i=R[]; i; i=R[i]) {
if (visit[col[i]])
continue; ++ret;
visit[col[i]] = true;
for (int j=D[i]; j!=i; j=D[j]) {
for (int k=R[j]; k!=j; k=R[k]) {
visit[col[k]] = true;
}
}
} return ret;
} void dfs(int d) {
int delta = H(); if (d+delta >= ansd)
return ; if (R[] == ) {
ansd = d;
return ;
} int c = R[];
for (int i=R[]; i; i=R[i]) {
if (S[i] < S[c])
c = i;
} for (int i=D[c]; i!=c; i=D[i]) {
remove_col(i);
for (int j=R[i]; j!=i; j=R[j]) {
remove_col(j);
}
dfs(d + );
for (int j=L[i]; j!=i; j=L[j]) {
restore_col(j);
}
restore_col(i);
}
} } DLX; typedef struct {
vector<LL> sq;
int sz;
} sqInfo_t; DLX solver;
const int maxm = ;
bool mark[maxm];
int valid[maxm];
int rowId[][];
int colId[][];
int n, tot;
LL st;
sqInfo_t sqInfo[]; void init_sq(int n) {
int cnt = ;
sqInfo_t& info = sqInfo[n];
vector<LL>& sq = info.sq;
int& sz = info.sz; rep(i, , n) {
rep(j, , n)
rowId[i][j] = cnt++;
rep(j, , n+)
colId[i][j] = cnt++;
}
rep(j, , n)
rowId[n][j] = cnt++; cnt = ;
rep(i, , n) {
rep(j, , n) {
rep(k, , n+) {
if (i+k>n || j+k>n)
break; LL val = ; // Top
rep(l, , k) {
val |= (1LL << rowId[i][j+l]);
} // Left
rep(l, , k) {
val |= (1LL << colId[i+l][j]);
} // Down
rep(l, , k) {
val |= (1LL << rowId[i+k][j+l]);
} // Right
rep(l, , k) {
val |= (1LL << colId[i+l][j+k]);
} sq.pb(val);
++sz;
}
}
}
} void init() {
rep(i, , )
init_sq(i);
} void solve() {
const vector<LL>& sq = sqInfo[n].sq;
const int& sz = sqInfo[n].sz;
int m = ; rep(i, , sz) {
if ((st & sq[i]) == sq[i]) {
valid[m++] = i;
}
} if (m == ) {
puts("");
return ;
} solver.init(m); rep(i, , tot) {
if (mark[i]) {
vi vc; rep(j, , m) {
if (sq[valid[j]] & (1LL << i))
vc.pb(j+);
} if (SZ(vc) > ) {
solver.addRow(vc);
}
}
} solver.dfs();
int ans = solver.ansd; printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; init();
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
memset(mark, true, sizeof(mark));
tot = n*(n+)*;
int k, x;
st = (1LL << tot) - ; scanf("%d", &k);
while (k--) {
scanf("%d", &x);
mark[--x] = false;
st ^= (1LL << x);
}
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

4. 数据生成器

 import sys
import string
from random import randint, shuffle def GenData(fileName):
with open(fileName, "w") as fout:
t = 20
fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(1, 5)
tot = n * (n + 1)
taken = randint(1, tot)
L = range(1, tot+1)
shuffle(L)
fout.write("%d %d\n" % (n, taken))
fout.write(" ".join(map(str, L[:taken])) + "\n") def MovData(srcFileName, desFileName):
with open(srcFileName, "r") as fin:
lines = fin.readlines()
with open(desFileName, "w") as fout:
fout.write("".join(lines)) def CompData():
print "comp"
srcFileName = "F:\Qt_prj\hdoj\data.out"
desFileName = "F:\workspace\cpp_hdoj\data.out"
srcLines = []
desLines = []
with open(srcFileName, "r") as fin:
srcLines = fin.readlines()
with open(desFileName, "r") as fin:
desLines = fin.readlines()
n = min(len(srcLines), len(desLines))-1
for i in xrange(n):
ans2 = int(desLines[i])
ans1 = int(srcLines[i])
if ans1 > ans2:
print "%d: wrong" % i if __name__ == "__main__":
srcFileName = "F:\Qt_prj\hdoj\data.in"
desFileName = "F:\workspace\cpp_hdoj\data.in"
GenData(srcFileName)
MovData(srcFileName, desFileName)

【POJ】1084 Square Destroyer的更多相关文章

  1. 【POJ】1704 Georgia and Bob(Staircase Nim)

    Description Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, ...

  2. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  3. 【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉

    DP/单调队列优化 首先不考虑奶牛的喜欢区间,dp方程当然是比较显然的:$ f[i]=min(f[k])+1,i-2*b \leq k \leq i-2*a $  当然这里的$i$和$k$都是偶数啦~ ...

  4. 【POJ】【2104】区间第K大

    可持久化线段树 可持久化线段树是一种神奇的数据结构,它跟我们原来常用的线段树不同,它每次更新是不更改原来数据的,而是新开节点,维护它的历史版本,实现“可持久化”.(当然视情况也会有需要修改的时候) 可 ...

  5. 【POJ】1222 EXTENDED LIGHTS OUT

    [算法]高斯消元 [题解] 高斯消元经典题型:异或方程组 poj 1222 高斯消元详解 异或相当于相加后mod2 异或方程组就是把加减消元全部改为异或. 异或性质:00 11为假,01 10为真.与 ...

  6. 【POJ】2892 Tunnel Warfare

    [算法]平衡树(treap) [题解]treap知识见数据结构 在POJ把语言从G++换成C++就过了……??? #include<cstdio> #include<algorith ...

  7. 【POJ】【1637】Sightseeing tour

    网络流/最大流 愚人节快乐XD 这题是给一个混合图(既有有向边又有无向边),让你判断是否有欧拉回路…… 我们知道如果一个[连通]图中每个节点都满足[入度=出度]那么就一定有欧拉回路…… 那么每条边都可 ...

  8. 【poj】1001

    [题目] ExponentiationTime Limit: 500MS Memory Limit: 10000KTotal Submissions: 123707 Accepted: 30202De ...

  9. 【POJ】3070 Fibonacci

    [算法]矩阵快速幂 [题解] 根据f[n]=f[n-1]+f[n-2],可以构造递推矩阵: $$\begin{vmatrix}1 & 1\\ 1 & 0\end{vmatrix} \t ...

随机推荐

  1. ASP.NET MVC +EasyUI 权限设计(二)环境搭建

    请注明转载地址:http://www.cnblogs.com/arhat 今天突然发现博客园出问题了,老魏使用了PC,手机,平板都访问博客园了,都是不能正常的访问,原因是不能加载CSS,也就是不能访问 ...

  2. 在wamp下PHP5.5安装php-redis扩展

    windows下开发用的xampp集成的环境,想装个php-redis扩展,扩展的github地址: https://github.com/nicolasff/phpredis 描述里找到window ...

  3. iTween基础之Punch(摇晃)

    一.基础介绍:二.基础属性 原文地址 : http://blog.csdn.net/dingkun520wy/article/details/50828042 一.基础介绍 PunchPosition ...

  4. D2GS1.11 的DC Key的相關設置指南

    D2GS1.11版本暗黑戰網服務器DC Key 的相關設置是保存在 D2Server.ini 文件中的.在這裡我列舉跟DC Key 有關的配置條款. (以下內容具存在於D2Server.ini 文件中 ...

  5. Fixing:insert_modules not found

    搞linux的最怕的就是panic.满屏的报错不知头绪,百度出来的还都是抄来抄去的垃圾. 我遇到的错误已经解决,所以不想再看到报错了..google出来两个没有上下文的文本,因为和他们差不多,在下面贴 ...

  6. 处理一则MySQL Slave环境出现ERROR 1201 (HY000): Could not initialize master info structure的案例

    mysql> start slave; ERROR (HY000): Slave failed to initialize relay log info structure from the r ...

  7. ?--Porg.springframework.beans.MethodInvocationException: Property 'username' threw exception; nested exception is java.lang.NullPointerException

    使用BoneCP作为连接池,在启动Tomcat报出以下异常: 一月 02, 2016 2:12:17 下午 org.apache.tomcat.util.digester.SetPropertiesR ...

  8. 使用Forms进行身份验证(Asp.net)

    1.背景      以往项目登陆后的用户信息都是存放在session中,但session有一个问题就是读取的时候需要先实例化所在类,在调用对象()如果用static修饰,则可能到时多次登陆sessio ...

  9. centos6.5安装vmware-tools

    一.问题描述 为什么使用vmware-tools:传文件方便,可以从主机中直接拖拽文件到centos中(但实际上我们可以用:WinSCP):鼠标切换方便,鼠标指到什么地方,表名当前正在操作哪个环境(但 ...

  10. sql查询结果本身要被使用两次

    一.问题 查询用户所有的错题数目到前端展示,要求展示的时候要有错题的编号,从1开始递增.如果删除了第5题,则将后面的题编号均向前挪. 二.分析 错题是在用户每次做题过程中插入到错题表中的,或者将题目推 ...