zoukankan      html  css  js  c++  java
  • 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 ",bound);
    }
    }
  • 相关阅读:
    23种设计模式
    外部排序:选择置换、败者树
    java代理模式
    java中抽象类和接口的异同(原文作者:博客园 海子)
    java中的垃圾回收
    进程
    C标准库-数值字符串转换与内存分配函数
    文件操作
    字符串操作
    C指针(二)
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/4871061.html
Copyright © 2011-2022 走看看