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

2
2
0
3
3 12 17 23

Sample Output

3
3

题意:t组数据,给出n代表n*n的网格,给一个值k,然后k个值,表示去掉k所代表的边,问还需要最少去掉几条边可以使得网格中没有正方形。

思路:

评估函数:每出现一个正方形,就删去其含有的边,然后继续扫描正方形,这样计数出来的次数比实际需要次数小(因为一次删去了多条边)

对于网格中正方形的枚举:

①先枚举正方形大小,1 <= size <= n;

②枚举网格每行最左边的火柴

③对于每个行位置,枚举该行可以成为该size大小正方形的最左边火柴

④标记该正方形的所有上边界和下边界(知道size和上边界最左火柴很容易求得)

 标记该正方形的所有左边界和有边界

(代码借鉴网上,侵删)

stick【i】表示含有i火柴的正方形编号

square【i】表示i正方形所含火柴编号

 
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std; int t;
int totsquare,totstick,base;
vector<int>stick[],square[];
int n,k;
int ans;
int exi[],tmp[]; int cal()
{
int res = ;
for(int i=;i<=totsquare;i++)tmp[i] = exi[i];
for(int i=;i<=totsquare;i++)if(!tmp[i])
{
res++;
for(int j=;j<square[i].size();j++)
{
for(int l=;l<stick[square[i][j]].size();l++)
{
tmp[stick[square[i][j]][l]]--;
}
}
}
return res;
} bool dfs(int sum,int lim)
{
if(sum + cal() > lim)return ;
int tmp = ;
while(exi[tmp] < && tmp <= totsquare)tmp++;
if(tmp > totsquare)
{
ans = min(ans,sum);
return ;
}
for(int i=;i<square[tmp].size();i++)
{
int sti = square[tmp][i];
for(int j=;j<stick[sti].size();j++)
{
exi[stick[sti][j]]--;
}
if(dfs(sum+,lim))return ;
for(int j=;j<stick[sti].size();j++)
{
exi[stick[sti][j]]++;
}
}
return ;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
totsquare = ,totstick = *n*(n+),base = *n+;
for(int i=; i<; i++)
{
stick[i].clear();
square[i].clear();
}
for(int sz=; sz<=n; sz++)
{
for(int i=; (i-)/base+sz<=n; i+=base)
{
for(int j=i; j-i+sz<=n; j++)
{
totsquare++;
for(int l=j; l-j<sz; l++) // 正方形上下边界标记
{
square[totsquare].push_back(l);
square[totsquare].push_back(l+sz*base);
stick[l].push_back(totsquare);
stick[l+sz*base].push_back(totsquare);
}
for(int l=j+n; (l-j-sz)/base<sz; l+=base) //正方形左右边界标记
{
square[totsquare].push_back(l);
square[totsquare].push_back(l+sz);
stick[l].push_back(totsquare);
stick[l+sz].push_back(totsquare);
}
}
}
}
memset(exi,,sizeof(exi));
for(int i=; i<=k; i++)
{
int t_st;
scanf("%d",&t_st);
for(int j=; j<stick[t_st].size(); j++)
{
exi[stick[t_st][j]]--;
}
totstick--;
}
ans = totstick;
for(int maxd=;; maxd++)
{
if(dfs(,maxd))
{
printf("%d\n",ans);
break;
}
}
}
}

Square Destroyer-POJ 1084 (IDA*)的更多相关文章

  1. Booksort POJ - 3460 (IDA*)

    Description The Leiden University Library has millions of books. When a student wants to borrow a ce ...

  2. POJ题目(转)

    http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html 初期:一.基本算法:     (1)枚举. (poj1753,poj29 ...

  3. Repeater POJ - 3768 (分形)

    Repeater POJ - 3768 Harmony is indispensible in our daily life and no one can live without it----may ...

  4. UVA - 10384 The Wall Pusher(推门游戏)(IDA*)

    题意:从起点出发,可向东南西北4个方向走,如果前面没有墙则可走:如果前面只有一堵墙,则可将墙向前推一格,其余情况不可推动,且不能推动游戏区域边界上的墙.问走出迷宫的最少步数,输出任意一个移动序列. 分 ...

  5. Radar Installation POJ - 1328(贪心)

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. ...

  6. Best Cow Fences POJ - 2018 (二分)

    Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field contains ...

  7. E - The Balance POJ - 2142 (欧几里德)

    题意:有两种砝码m1, m2和一个物体G,m1的个数x1,  m2的个数为x2, 问令x1+x2最小,并且将天平保持平衡 !输出  x1 和 x2 题解:这是欧几里德拓展的一个应用,欧几里德求不定方程 ...

  8. 人类即将进入互联网梦境时代(IDA)

    在电影<盗梦空间>中,男主角科布和妻子在梦境中生活了50年,从楼宇.商铺.到河流浅滩.一草一木.这两位造梦师用意念建造了属于自己的梦境空间.你或许并不会想到,在不久未来,这看似科幻的情节将 ...

  9. POJ 2286 The Rotation Game(IDA*)

    The Rotation Game Time Limit: 15000MS   Memory Limit: 150000K Total Submissions: 6396   Accepted: 21 ...

随机推荐

  1. C# WINFORM 编程中,选择**文件夹**而不是文件的方法(转)

    我们选择文件可以用 OpenFileDialog ,但是文件夹有两种方法. 法一: 用C#的FolderNameEditor类的子类FolderBrowser类来实现获取浏览文件夹对话框的功能.下面来 ...

  2. Swift 学习- 04 -- 字符串和字符

    // 字符串 和 字符 // 字符串 是有序的 Character (字符) 类型的值的集合,  通过 String 类型的集合 // swift 的 String 和 Character 类型提供了 ...

  3. web前端识别文字转语音

    const msg = new SpeechSynthesisUtterance("hello world"); window.speechSynthesis.speak(msg) ...

  4. zoj3659

    #include<iostream> #include<algorithm> #include<cstring> #define ll long long #inc ...

  5. Fiddler抓包6-get请求(url详解)

    前言 上一篇介绍了Composer的功能,可以模拟get和post请求,get请求有些是不带参数的,这种比较容易,直接放到url地址栏就行.有些get请求会带有参数,本篇详细介绍url地址格式. 一. ...

  6. 从xtrabackup备份恢复单表

    目前对MySQL比较流行的备份方式有两种,一种上是使用自带的mysqldump,另一种是xtrabackup,对于数据时大的环境,普遍使用了xtrabackup+binlog进行全量或者增量备份,那么 ...

  7. spring cloud Hystrix监控面板Hystrix Dashboard和Turbine

    我们提到断路器是根据一段时间窗内的请求情况来判断并操作断路器的打开和关闭状态的.而这些请求情况的指标信息都是HystrixCommand和HystrixObservableCommand实例在执行过程 ...

  8. git 小乌龟安装教程

    一.windows系统安装git 首先下载git for windows客户端http://msysgit.github.io/ 安装过程没什么特别的,不停next就ok了     图太多就不继续了~ ...

  9. Android 网络请求框架

    1.okHttp 特点 简单.灵活.无连接.无状态 优势: 谷歌官方API在6.0之后在Android SDK中移除了HttpClient,然后他火了起来, 他支持SPDY(谷歌开发的基于TCP应用层 ...

  10. javaScript中的querySelector()与querySelectorAll()的区别

    之前,在JavaScript获取文档元素一文中,我曾介绍了获取文档元素的几种方法,最后一种方法是通过选择器获取文档元素.它的核心思想便是利用querySelector()或querySelectorA ...