UVA 1603 Square Destroyer

题意:

  给定一个火柴棒拼成的方格阵,然后去掉一些火柴棒,问至少再去掉几根火柴棒能够让图中一个正方形都没有。

思路:

1. 由于题目中给定了 n 的范围,2 * n * (n + 1) <= 60 -> 所以能够保证所有的火柴用 long long的位运算表示;

2. 启发式函数 h 的计算需要考量:如果删除了某个方阵的一个边,则能够保证 h(s1) <= h(s2) + C(s1, s2),其中 C(s1, s2) = 1,h(s1) - h(s2) <= 1;

3. 各种位运算的范围要明确,如 1<<i 前面要加上long long 修饰方能得到正确的结果

代码:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int INFS = 0x7fffffff;int N,C,E,bound;long long squ[100],xiao[6][6];bool flag;long long get2(int i){    return ((long long)1<<(i-1));}int getnumber1(int i,int j){    return (2*N+1)*(i-1)+j;}int getnumber2(int i,int j){    return (2*N+1)*(i-1)+j+N;}void build(){    C=0;    memset(xiao,0,sizeof(xiao));    int i,j;    for(i=1;i<=N;i++)        for(j=1;j<=N;j++)        {            xiao[i][j]|=get2(getnumber1(i,j))|get2(getnumber1(i+1,j));            xiao[i][j]|=get2(getnumber2(i,j))|get2(getnumber2(i,j+1));            squ[C++]=xiao[i][j];        }    for(int size=2;size<=N;size++)    {        for(i=1;i+size-1<=N;i++)        {            for(j=1;j+size-1<=N;j++)            {                squ[C]=0;                for(int a=0;a<size;a++)                {                    for(int b=0;b<size;b++)                    {                        squ[C]^=xiao[i+a][j+b];;                    }                }                C++;            }        }    }}int dfs(long long state,int de){    int h=0;    long long u=0,s=state;    for(int i=0;i<C;i++)    {        if((s&squ[i])==squ[i])        {            h+=1;            s^=squ[i];            if(u==0)               u=squ[i];        }    }    if(h==0)    {        flag=true;        return de;    }    if(de+h>bound)        return de+h;    int news=INFS;    for(int i=1;i<=E;i++)    {        if(u&get2(i))        {            int b=dfs(state^get2(i),de+1);            if(flag)                return b;            news=min(b,news);        }    }    return news;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&N);        build();        E=2*N*(N+1);        int k;        long long state=((long long)1<<E)-1;        scanf("%d",&k);        for(int i=0;i<k;i++)        {            int x;            scanf("%d",&x);            state^=get2(x);        }        flag=false;        bound=0;        while(!flag)        {            bound=dfs(state,0);        }        printf("%d\n",bound);    }}
时间: 2024-12-29 13:05:01

UVA 1603 Square Destroyer的相关文章

UVA 10023 - Square root(手算平方根)

题目:UVA 10023 - Square root(手算平方根) 题目链接 题目大意:求给定的一个数的平方根. 解题思路:用二分但是这个数太大了,就超时了.看题接后发现需要用一种手算平方根的算法. 算法: 先判断这个数是不是偶数位,是的话就第一次取前面的两位数,不是的话第一次就只取前面的一位数来作为被除数.接下来就是两位两位为一节来计算. 用前一次的计算结果乘上20+一个个位数a再乘上这个a,找到最大的a使得这个式子的结果不大于被除数. 被除数减去这个结果然后再在尾巴接上那个大数的接下来两位作

UVA 11542 - Square(高斯消元)

UVA 11542 - Square 题目链接 题意:给定一些数字,保证这些数字质因子不会超过500,求这些数字中选出几个,乘积为完全平方数,问有几种选法 思路:对每个数字分解成质因子后,发现如果要是完全平方数,选出来的数字的每个质因子个数都必然要是偶数,这样每个质因子可以列出一个异或的方程,如果数字包含质因子,就是有这个未知数,然后进行高斯消元,求出自由变量的个数,每个自由变量可以选或不选,这样的情况就是(2^个数),然后在扣掉什么都不选的1种就是答案了 代码: #include <cstdi

poj 1084 Square Destroyer dlx解重复覆盖

分析: 将问题转化为重复覆盖问题,DancingLink解决. 代码: //poj 1084 //sep9 #include <iostream> using namespace std; const int maxN=10024; const int maxL=128; int L[maxN],R[maxN],U[maxN],D[maxN]; int C[maxN],H[maxN]; int S[maxN],A[maxN],X[maxN]; bool makeup[maxL][maxL];

UVA 11461 Square Numbers解题报告

Discription A square number is an integer number whose square root is also an integer. For example 1, 4, 81 are some square numbers. Given two numbers a and b you will have to find out how many square numbers are there between a and b (inclusive). In

UVa1603 - Square Destroyer

题意: 给定一个火柴棒拼成的方格阵,然后去掉一些火柴棒,问至少再去掉几根火柴棒能够让图中一个正方形都没有. 思路: 1. 由于题目中给定了 n 的范围,2 * n * (n + 1) <= 60 -> 所以能够保证所有的火柴用 __int64 的位运算表示; 2. 问题的关键在于如何生成火柴构成的方阵,以及生成方阵之后如何去搜索; 3. 启发式函数 h 的计算需要考量:如果删除了某个方阵的一个边,则能够保证 h(s1) <= h(s2) + C(s1, s2),其中 C(s1, s2)

(中等) POJ 1084 Square Destroyer , DLX+可重复覆盖。

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

UVA - 11542 Square (异或方程组)

Given n integers you cangenerate 2n-1 non-empty subsets from them. Determine for howmany of these subsets the product of all the integers in that is a perfectsquare. For example for the set {4,6,10,15} there are3 such subsets. {4}, {6,10,15} and {4,6

UVA - 10023 - Square root (模拟手算开方)

题目传送:UVA - 10023 思路:模拟手算开方,不想用c/c++,感觉太麻烦了,就直接用的java里的BigInteger类来写的,写了好久......Java还是得看看书呀,手算开方参考的这里 AC代码: import java.util.Scanner; import java.math.BigInteger; public class Main { static void fun(BigInteger x) { String str; str = x.toString(); str

POJ 1084 Square Destroyer【舞蹈链】【重复覆盖】

建模很容易就能说清楚,但我一直想不出来. 要问为什么的话可能是因为这题要先预处理出来所有正方形,而我没做过要预处理的舞蹈链的题.所以想不到. 那就是预处理出来所有正方形,用一个long long来表示一个正方形,这个正方形有没有包含id这条边就用 (1<<id)&num判断.那怎么预处理所有正方形呢,枚举边长1-n的正方形,然后再枚举这个正方形左上方的顶点就能做出来. 然后就能建模了,火柴是行,所有按现有火柴能拼出来的正方形是列,与其说是精准覆盖倒也可以说是全部破坏. http://e