POJ_1084_SquareDestroyer(DancingLinksX重复覆盖)
2016-05-01 00:12
603 查看
Square Destroyer
Description
The left figure below shows a complete 3*3 grid made with 2*(3*4) (=24) matchsticks. The lengths of all matchsticks are one. You can find many squares of different sizes in the grid. The size of a square is the length of its side. In the grid shown in the left
figure, there are 9 squares of size one, 4 squares of size two, and 1 square of size three.
Each matchstick of the complete grid is identified with a unique number which is assigned from left to right and from top to bottom as shown in the left figure. If you take some matchsticks out from the complete grid, then some squares in the grid will be destroyed,
which results in an incomplete 3*3 grid. The right figure illustrates an incomplete 3*3 grid after removing three matchsticks numbered with 12, 17 and 23. This removal destroys 5 squares of size one, 3 squares of size two, and 1 square of size three. Consequently,
the incomplete grid does not have squares of size three, but still has 4 squares of size one and 1 square of size two.
As input, you are given a (complete or incomplete) n*n grid made with no more than 2n(n+1) matchsticks for a natural number 5 <= n . Your task is to compute the minimum number of matchsticks taken
out to destroy all the squares existing in the input n*n grid.
Input
The input consists of T test cases. The number of test cases (T ) is given in the first line of the input file.
Each test case consists of two lines: The first line contains a natural number n , not greater than 5, which implies you are given a (complete or incomplete) n*n grid as input, and the second line begins with a nonnegative integer k , the number of matchsticks
that are missing from the complete n*n grid, followed by
k numbers specifying the matchsticks. Note that if k is equal to zero, then the input grid is a complete n*n grid; otherwise, the input grid is an incomplete n*n grid such that the specified k matchsticks are missing from the complete n*n grid.
Output
Print exactly one line for each test case. The line should contain the minimum number of matchsticks that have to be taken out to destroy all the squares in the input grid.
Sample Input
Sample Output
Source
Taejon 2001
DancingLinksX重复覆盖题目
题意给出一个火柴码成的矩阵(类似于矩阵)
然后其中某些火柴是没有的
问至少再拿走多少可以使所有的方形破坏掉
做法
火柴作为行,方形作为列
这题主要麻烦的地方就在于要把火柴对应到方形去
于是想了好久的对应关系
火柴分布如下
用init初始化了那样一个矩阵
剩下的就好办了
跑模板即可……
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 3642 | Accepted: 1577 |
The left figure below shows a complete 3*3 grid made with 2*(3*4) (=24) matchsticks. The lengths of all matchsticks are one. You can find many squares of different sizes in the grid. The size of a square is the length of its side. In the grid shown in the left
figure, there are 9 squares of size one, 4 squares of size two, and 1 square of size three.
Each matchstick of the complete grid is identified with a unique number which is assigned from left to right and from top to bottom as shown in the left figure. If you take some matchsticks out from the complete grid, then some squares in the grid will be destroyed,
which results in an incomplete 3*3 grid. The right figure illustrates an incomplete 3*3 grid after removing three matchsticks numbered with 12, 17 and 23. This removal destroys 5 squares of size one, 3 squares of size two, and 1 square of size three. Consequently,
the incomplete grid does not have squares of size three, but still has 4 squares of size one and 1 square of size two.
As input, you are given a (complete or incomplete) n*n grid made with no more than 2n(n+1) matchsticks for a natural number 5 <= n . Your task is to compute the minimum number of matchsticks taken
out to destroy all the squares existing in the input n*n grid.
Input
The input consists of T test cases. The number of test cases (T ) is given in the first line of the input file.
Each test case consists of two lines: The first line contains a natural number n , not greater than 5, which implies you are given a (complete or incomplete) n*n grid as input, and the second line begins with a nonnegative integer k , the number of matchsticks
that are missing from the complete n*n grid, followed by
k numbers specifying the matchsticks. Note that if k is equal to zero, then the input grid is a complete n*n grid; otherwise, the input grid is an incomplete n*n grid such that the specified k matchsticks are missing from the complete n*n grid.
Output
Print exactly one line for each test case. The line should contain the minimum number of matchsticks that have to be taken out to destroy all the squares in the input grid.
Sample Input
2 2 0 3 3 12 17 23
Sample Output
3 3
Source
Taejon 2001
DancingLinksX重复覆盖题目
题意给出一个火柴码成的矩阵(类似于矩阵)
然后其中某些火柴是没有的
问至少再拿走多少可以使所有的方形破坏掉
做法
火柴作为行,方形作为列
这题主要麻烦的地方就在于要把火柴对应到方形去
于是想了好久的对应关系
火柴分布如下
/*
1
1
2 3
4
2
1 2
3 4 5
6 7
8 9 10
11 12
3
1 2 3
4 5 6 7
8 9 10
11 12 13 14
15 16 17
18 19 20 21
22 23 24
4
1 2 3 4
5 6 7 8 9
10 11 12 13
14 15 16 17 18
19 20 21 22
23 24 25 26 27
28 29 30 31
32 33 34 35 36
37 38 39 40
5
1 2 3 4 5
6 7 8 9 10 11
12 13 14 15 16
17 18 19 20 21 22
23 24 25 26 27
28 29 30 31 32 33 34 35 36 37 38
39 40 41 42 43 44
45 46 47 48 49
50 51 52 53 54 55
56 57 58 59 60
*/
用init初始化了那样一个矩阵
剩下的就好办了
跑模板即可……
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int MN=65;//最多60根火柴 const int MM=1+2*2+3*3+4*4+5*5+5;//方形数量 const int MNN=MN*MM+MM; //最大点数 struct DLX { int n,m,si;//n行数m列数si目前有的节点数 //十字链表组成部分 int U[MNN],D[MNN],L[MNN],R[MNN],Row[MNN],Col[MNN]; //第i个结点的U向上指针D下L左R右,所在位置Row行Col列 int H[MN],S[MM]; //记录行的选择情况和列的覆盖情况 int ansd,ans[MN]; //ansd为最值 void init(int _n,int _m) //初始化空表 { n=_n; m=_m; for(int i=0;i<=m;i++) //初始化第一横行(表头) { S[i]=0; U[i]=D[i]=i; //目前纵向的链是空的 L[i]=i-1; R[i]=i+1; //横向的连起来 } R[m]=0;L[0]=m; si=m; //目前用了前0~m个结点 for(int i=1;i<=n;i++) H[i]=-1; } void link(int r,int c) //插入点(r,c) { ++S[Col[++si]=c]; //si++;Col[si]=c;S[c]++; Row[si]=r; D[si]=D[c]; U[D[c]]=si; U[si]=c; D[c]=si; if(H[r]<0) H[r]=L[si]=R[si]=si; else { R[si]=R[H[r]]; L[R[H[r]]]=si; L[si]=H[r]; R[H[r]]=si; } } void remove(int c) { for(int i=D[c];i!= c;i= D[i]) L[R[i]]=L[i],R[L[i]]=R[i]; } void resume(int c) { for(int i=U[c];i!= c;i=U[i]) L[R[i]]=R[L[i]]=i; } bool v[MNN]; int h() //估值 { int ret=0; for(int c=R[0];c!=0;c=R[c]) v[c]=1; for(int c=R[0];c!=0;c=R[c]) if(v[c]) { ret++; v[c]=0; for(int i=D[c];i!=c;i=D[i]) for(int j=R[i];j!=i;j=R[j]) v[Col[j]]=0; } return ret; } void dance(int d) { if(d+h()>=ansd) //利用A*优化 return; if(R[0]==0) { ansd=d; return; } int c=R[0]; for(int i=R[0];i!=0;i=R[i]) if(S[i]<S[c]) c=i; for(int i=D[c];i!=c;i=D[i]) { remove(i); for(int j=R[i];j!=i;j=R[j]) remove(j); dance(d+1); for(int j = L[i];j != i;j = L[j]) resume(j); resume(i); } } }dlx; int match[6][MN][MM];//矩阵大小,火柴标号,对应小框子 int nsq[6];//方格多少 void init() { for(int ii=1;ii<=5;ii++) //总方格边长 { int cnt=0; for(int jj=1;jj<=ii;jj++)//小方格大小 { for(int i=1;i<=ii+1-jj;i++)//起点横坐标 for(int j=0;j<ii+1-jj;j++)//起点纵坐标 { cnt++; for(int k=0;k<jj;k++) //上边 match[ii][i+j*(2*ii+1)+k][++match[ii][i+j*(2*ii+1)+k][0]]=cnt; for(int k=0;k<jj;k++) //下边 match[ii][i+(j+jj)*(2*ii+1)+k][++match[ii][i+(j+jj)*(2*ii+1)+k][0]]=cnt; for(int k=0;k<jj;k++) //左边 match[ii][i+ii+(j+k)*(2*ii+1)][++match[ii][i+ii+(j+k)*(2*ii+1)][0]]=cnt; for(int k=0;k<jj;k++) //右边 match[ii][i+ii+jj+(j+k)*(2*ii+1)][++match[ii][i+ii+jj+(j+k)*(2*ii+1)][0]]=cnt; } } nsq[ii]=cnt; } } int isu[MM]; int ma[MM]; int main() { int t,n,k; scanf("%d",&t); init(); while(t--) { scanf("%d%d",&n,&k); int nu; memset(isu,0,sizeof(isu)); memset(ma,0,sizeof(ma)); for(int i=1;i<=k;i++) { scanf("%d",&nu); for(int j=1;j<=match [nu][0];j++) isu[match [nu][j]]=1; } int nisu=0; //去掉无用的行 for(int i=1;i<=nsq ;i++) if(!isu[i]) ma[i]=++nisu; dlx.init(2*n*(n+1),nisu); for(int i=1;i<=2*n*(n+1);i++) { for(int j=1;j<=match [i][0];j++) if(ma[match [i][j]]) dlx.link(i,ma[match [i][j]]); } dlx.ansd=1e5; dlx.dance(0); printf("%d\n",dlx.ansd); } return 0; }
相关文章推荐
- pathspec did not match any file known to git
- iOS边练边学--AFNetWorking框架GET、Post、Download、Upload,数据解析模式以及监控联网状态
- readLine方法的简单练习,回答2016-04-27 的帖子的问题
- L1 L2正则化
- Java基础串理
- 知识联结梳理 : I/O多路复用、EPOLL(SELECT/POLL)、NIO、Event-driven、Reactor模式
- python错误
- Appcan与后台数据交互,登录例子
- GIT 服务器 安装常见问题的排除
- Laravel小技巧
- ListView加Fragment实现Flyme4.0设置界面
- 【世界是自己的,与他人毫无关系】--杨绛
- 【Unity3d】浅谈异步加载场景
- 2016 UESTC Training for Data Structures R - Japan 树状数组求逆序数
- 2016 UESTC Training for Data Structures Q - 昊昊爱运动 II 线段树+延迟操作+bitset
- 2016 UESTC Training for Data Structures O - 卿学姐种美丽的花 树状数组+等差数列
- FZU_1686_神龙的难题(DancingLinksX重复覆盖)
- 0-1背包的优化
- 以太网之物理层
- LUA OOP 单例模式实现的 一个 方案