poj1084Square Destroyer(LDX de duplication coverage)

Posted by zunebuggy on Wed, 16 Oct 2019 19:40:52 +0200

Original link: http://www.cnblogs.com/riasky/p/3481929.html

Please stamp here

Abstract: for a n*n grid diagram made up of wooden sticks of unit length, number each stick according to the figure, with the number range of 1~2*n*(n+1). Now k wooden sticks have been removed from the diagram, and it is required to remove at least a few wooden sticks so that there is no square in the grid diagram. That is, destroy all squares in the diagram. N is no more than 5.

Topic analysis: n is too small, direct search! dancing links optimization. Transform it into a repeated coverage model.

In the complete grid graph of n*n, there are n*(n+1)*(2*n+1)/6 squares. Give each number, and then give it in the number graph of the small wooden stick, and press that. Then the small wooden stick is row, square is column, and the graph is built.

Note that the given k sticks should be removed. First, the square covered by the k sticks need not be mapped, and then the k heads should also be deleted.

Then about the relationship between the broken square of the stick number. It seems to be very complicated, but because n is too small, then I made a watch.... but it's hard to count. It's been a night...

The number of squares is from 1 to n * (n + 1) * (2 * n + 1) / 6, and the sequence is from the upper left corner to the lower right corner in increasing side length.

See code:

 

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 6;
const int M = 4000;//3300
const int NM = 56;//Maximum number of squares
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


 

 

Reproduced at: https://www.cnblogs.com/riasky/p/3481929.html