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. Java的动手动脑(六)

    日期:2018.11.8 星期四 博客期:022 --------------------------------------------------------------------------- ...

  2. 2。创建第一个angular应用,已经开发前的一些配置

    现在我们开始新建一个angular5的脚手架  . 到想要建项目的目录下.比如我的 在  D:\JsProjects 进入cmd或者powershell cd 进入该文件夹下 然后开始新建,ng ne ...

  3. java多线程快速入门(十七)

    多线程通讯实例(必须要有多个线程.必须要管理同一个变量:线程A生产一个变量,线程B消费一个变量) package com.cppdy; class User { public String usern ...

  4. java----static关键字(包括final)

    static修饰字段: 使用static关键字修饰一个字段:声明的static变量实际上就是一个全局变量 使用static关键字修饰一个方法:可以直接使用类调用方法,和对象没有关系了 使用static ...

  5. CF558E

    非常好的一道题,是线段树的常见玩法 将字符串转化为1~26个数 对区间开一棵线段树,用两个数组分别维护区间中1~26每个数的个数以及一个区间覆盖标记,表示这个区间是否被某一个值覆盖了 在每次排序时,首 ...

  6. Springboot+MyBatis+JPA集成

      1.前言 Springboot最近可谓是非常的火,本人也在项目中尝到了甜头.之前一直使用Springboot+JPA,用了一段时间发现JPA不是太灵活,也有可能是我不精通JPA,总之为了多学学Sp ...

  7. 如何录制Chrome或者Linux下的应用

    说明: PortMapping的这种用法其实早就有了,开始我一直没注意到这点,后面才发现了这个功能,特别在<性能测试进阶指南Loadrunner11实战>第二版中更新. 不是所有的对象都能 ...

  8. python unittest装载、执行、造成报告

    #执行用例 caselist = config.caselist for i in range(0,len(caselist)): reportname = caselist[i][2:] now = ...

  9. 论文阅读笔记三十七:Grid R-CNN(CVPR2018)

    论文源址:https://arxiv.org/abs/1811.12030 开源代码:未公开 摘要 本文提出了目标检测网络Grid R-CNN,其基于网格定位机制实现准确的目标检测.传统方法主要基于回 ...

  10. 上手TensorFlow

    tensorflow中softmax_cross_entropy和sparse_softmax_cross_entropy的区别 都是softmax cross entropy损失函数,区别在于lab ...