poj1084Square Destroyer(LDX解重复覆盖)

题目请戳这里

题目大意:给一个n*n的用单位长度的木棍拼起来的网格图,给每个木棍按图示编号,编号范围1~2*n*(n+1).现在已知图中已经去掉了k个木棍,求还要至少去掉几根木棍能使网格图中不存在正方形.即破坏图中所有的正方形.n不超过5.

题目分析:n太小了啦,直接爆搜!dancing links优化之.将之转化成一个重复覆盖的模型.

n*n的完全网格图中存在n*(n+1)*(2*n+1)/6个正方形.给每一个编号,然后小木棍的编号图中给了,就按那个来.然后小木棍为行,正方形为列,建图.

注意题目已经给定的k个木棍要去掉.首先那k个木棍覆盖的正方形是不用建图的,然后那k个表头也要删掉.

然后关于木棍编号破坏的正方形的关系.好像很复杂的样子,不过因为n太小了,然后我就打表了大笑..不过好难数,数了一晚上....哭

正方形编号从1~n*(n+1)*(2*n+1)/6,顺序按边长递增从左上角到右下角.

详情请见代码:

 

#include <iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

const int N = 6;

const int M = 4000;//3300

const int NM = 56;//最大正方形个数

int n,K,num,ans;

int h[M],s[M],u[M],d[M],l[M],r[M],col[M];

bool flag[NM],vis[NM];

int stk[NM];

int table[5][61][NM] = {

{

    {0},{1,1},{1,1},{1,1},{1,1},

},

{   {0},{2,1,5},{2,2,5},{2,1,5},{2,1,2},{2,2,5},{2,1,3},

    {2,2,4},{2,3,5},{2,3,4},{2,4,5},{2,3,5},{2,4,5},

},

{   {0},{3,1,10,14},{4,2,10,11,14},{3,3,11,14},{3,1,10,14},

    {3,1,2,11},{3,2,3,10},{3,3,11,14},{3,1,4,12},{4,2,5,12,13},

    {3,3,6,13},{4,4,10,12,14},{4,4,5,11,13},{4,5,6,10,12},

    {4,6,11,13,14},{3,4,7,10},{4,5,8,10,11},{3,6,9,11},

    {3,7,12,14},{3,7,8,13},{3,8,9,12},{3,9,13,14},

    {3,7,12,14},{4,8,12,13,14},{3,9,13,14},

},

{   {0},{4,1,17,26,30},{6,2,17,18,26,27,30},{6,3,18,19,26,27,30},{4,4,19,27,30},

    {4,1,17,26,30},{4,1,2,18,27},{4,2,3,17,19},{4,3,4,18,26},{4,4,19,27,30},

    {4,1,5,20,28},{5,2,6,20,21,29},{5,3,7,21,22,28},{4,4,8,22,29},

    {6,5,17,20,26,28,30},{6,5,6,18,21,27,29},{6,6,7,17,19,20,22},{6,7,8,18,21,26,28},{6,8,19,22,27,29,30},

    {4,5,9,17,23},{6,6,10,17,18,23,24},{6,7,11,18,19,24,25},{4,8,12,19,25},

    {6,9,20,23,26,28,30},{6,9,10,21,24,27,29},{6,10,11,20,22,23,25},{6,11,12,21,24,26,28},{6,12,22,25,27,29,30},

    {4,9,13,20,26},{5,10,14,20,21,27},{5,11,15,21,22,26},{4,12,16,22,27},

    {4,13,23,28,30},{4,13,14,24,29},{4,14,15,23,25},{4,15,16,24,28},{4,16,25,29,30},

    {4,13,23,28,30},{6,14,23,24,28,29,30},{6,15,24,25,28,29,30},{4,16,25,29,30},

},

{   {0},

    {5,1,26,42,51,55},{8,2,26,27,43,44,51,52,55},{9,3,27,28,42,43,44,51,52,55},{8,6,4,28,29,43,44,51,52,55},{5,5,29,44,52,55},

    {5,1,26,42,51,55},{5,1,2,27,43,52},{5,2,3,26,28,44},{5,3,4,27,29,42},{5,4,5,28,43,51},{5,5,29,44,52,55},

    {5,1,6,30,45,53},{8,2,7,30,31,45,46,53,54},{9,3,8,31,32,45,46,47,53,54},{8,4,9,32,33,46,47,53,54},{5,5,10,33,47,54},

    {8,6,26,30,42,45,51,53,55},{8,6,7,27,31,43,46,52,54},{8,7,8,26,28,30,32,44,47},{8,8,9,27,29,31,33,42,45},{8,9,10,28,32,43,46,51,53},{8,10,29,33,44,47,52,54,55},

    {5,6,11,26,34,48},{8,7,12,26,27,34,35,48,49},{9,8,13,27,28,35,36,48,49,50},{8,9,14,28,29,36,37,49,50},{5,10,15,29,37,50},

    {9,11,30,34,42,45,48,51,53,55},{9,11,12,31,35,43,46,49,52,54},{9,12,13,30,32,34,36,44,47,50},{9,13,14,31,33,35,37,42,45,48},{9,14,15,32,36,43,46,49,51,53},{9,15,33,37,44,47,50,52,54,55},

    {5,11,16,30,38,42},{8,12,17,30,31,38,39,42,43},{9,13,18,31,32,39,40,42,43,44},{8,14,19,32,33,40,41,43,44},{5,15,20,33,41,44},

    {8,16,34,38,45,48,51,53,55},{8,16,17,35,39,46,49,52,54},{8,17,18,34,36,38,40,47,51},{8,18,19,35,37,39,41,45,48},{8,19,20,36,40,46,49,51,53},{8,20,37,41,47,50,52,54,55},

    {5,16,21,34,45,51},{8,17,22,34,35,45,46,51,52},{9,18,23,35,36,45,46,47,51,52},{8,19,24,36,37,46,47,51,52},{5,20,25,37,47,52},

    {5,21,38,48,53,55},{5,21,22,39,49,54},{5,22,23,38,40,50},{5,23,24,39,41,48},{5,24,25,40,49,53},{5,25,41,50,54,55},

    {5,21,38,48,53,55},{8,22,38,39,48,49,53,54,55},{9,23,39,40,48,49,50,53,54,55},{8,24,40,41,49,50,53,54,55},{5,25,41,50,54,55},

}

};



void init()

{

    int i,c;

    memset(h,0,sizeof(h));

    memset(s,0,sizeof(s));

    c = n * (n + 1) * (2 * n + 1)/6;

    for(i = 0;i <= c;i ++)

    {

        u[i] = d[i] = i;

        l[i] = (i + c)%(c + 1);

        r[i] = (i + 1)%(c + 1);

    }

    num = c + 1;

}

void ins(int i,int j)

{

    if(h[i])

    {

        r[num] = h[i];

        l[num] = l[h[i]];

        l[r[num]] = r[l[num]] = num;

    }

    else

    {

        h[i] = num;

        l[num] = r[num] = num;

    }

    s[j] ++;

    u[num] = u[j];

    d[num] = j;

    d[u[j]] = num;

    u[j] = num;

    col[num] = j;

    num ++;

}

void del(int c)

{

    for(int i = d[c];i != c;i = d[i])

        l[r[i]] = l[i],r[l[i]] = r[i];

}

void recover(int c)

{

    for(int i = u[c];i != c;i = u[i])

        l[r[i]] = r[l[i]] = i;

}

int A()

{

    int i,j,k,ret;

    ret = 0;

    memset(vis,false,sizeof(vis));

    for(i = r[0];i;i = r[i])

    {

        if(vis[i] == false)

        {

            ret ++;

            vis[i] = true;

            for(j = d[i];j != i;j = d[j])

                for(k = r[j];j != k;k = r[k])

                    vis[col[k]] = true;

        }

    }

    return ret;

}

void dfs(int k)

{

    if(k + A() >= ans)

        return;

    if(!r[0])

    {

        ans = min(ans,k);

        return ;

    }

    int mn = M;

    int c,i,j;

    for(i = r[0];i;i = r[i])

    {

        if(s[i] < mn)

        {

            mn = s[i];

            c = i;

        }

    }

    for(i = d[c];i != c;i = d[i])

    {

        del(i);

        for(j = r[i];j != i;j = r[j])

            del(j);

        dfs(k + 1);

        for(j = l[i];j != i;j = l[j])

            recover(j);

        recover(i);

    }

}



void build()

{

    scanf("%d",&n);

    memset(flag,false,sizeof(flag));



    scanf("%d",&K);

    int i,j;

    for(i = 1;i <= K;i ++)

    {

        scanf("%d",&stk[i]);

        for(j = 1;j <= table[n - 1][stk[i]][0];j ++)

            flag[table[n - 1][stk[i]][j]] = true;

    }

    init();

    for(i = 1;i <= (n + 1) * n * 2;i ++)

    {

        for(j = 1;j <= table[n - 1][i][0];j ++)

            if(flag[table[n - 1][i][j]] == false)

                ins(i,table[n - 1][i][j]);

    }

    int nmgb = 0;

    for(i = 1;i <= n * (n + 1) * (n * 2 + 1)/6;i ++)

        if(flag[i])

            l[r[i]] = l[i],r[l[i]] = r[i];

}

void fuck()

{

    ans = M;

    dfs(0);

    printf("%d\n",ans);

}

int main()

{

    int t;scanf("%d",&t);

    while(t --)

    {

        build();

        fuck();

    }

    return 0;

}

//244K	0MS




 

 

你可能感兴趣的:(des)