【POJ 1084】 很烦人的DLX

原创 2011年10月14日 20:02:31
 

DLX。。。

一开始读错题目了。。。是要把所有正方形都消掉!!!

代码里面有两种统计正方形和火柴的方法,都值得借鉴。。Orz


发一下代码

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int head=0;
const int INF=10000000;
const int maxn = 1000;
const int maxd = 10000;
int cnt, res;
int mat[maxn][maxn], s[maxn], l[maxd], r[maxd], u[maxd], d[maxd], c[maxd], o[maxn], row[maxd];
bool use[maxn];
void makegragh(int &n, int &m)
{
    memset(mat, 0, sizeof(mat));
//初始化mat矩阵
}
void initial(int n, int m)
{
    memset(use, false, sizeof(use));
    res=n+1;
    int i, j, rowh;
    memset(s, 0, sizeof(s));
    for(i=head; i<=m; i++)
    {
        r[i]=(i+1)%(m+1);
        l[i]=(i-1+m+1)%(m+1);
        u[i]=d[i]=i;
    }
    cnt=m+1;
    for(i=1; i<=n; i++)
    {
        rowh=-1;
        for(j=1; j<=m; j++)
        {
            //printf("%d", mat[i][j]);
            if(mat[i][j])
            {
                s[j]++;
                u[cnt]=u[j];
                d[u[j]]=cnt;
                u[j]=cnt;
                d[cnt]=j;
                row[cnt]=i;
                c[cnt]=j;
                if(rowh==-1)
                {
                    l[cnt]=r[cnt]=cnt;
                    rowh=cnt;
                }
                else
                {
                    l[cnt]=l[rowh];
                    r[l[rowh]]=cnt;
                    r[cnt]=rowh;
                    l[rowh]=cnt;
                }
                cnt++;
            }
        }
        //puts("");
    }
}
void remove(int c)
{
    for(int i=d[c]; i!=c; i=d[i])
    {
        r[l[i]]=r[i];
        l[r[i]]=l[i];
    }
}
void resume(int c)
{
    for(int i=d[c]; i!=c; i=d[i])
        r[l[i]]=l[r[i]]=i;
}
int h()
{
    bool has[maxn];
    memset(has, false, sizeof(has));
    int ans=0;
    for(int i=r[head]; i!=head; i=r[i])
        if(!has[i])
        {
            ans++;
            for(int j=d[i]; j!=i; j=d[j])
                for(int k=r[j]; k!=j; k=r[k])
                    has[c[k]]=true;
        }
    return ans;
}
bool dfs(int k)
{
    if(k+h()>=res)return false;//A* cut

    if(r[head]==head)
    {
        if(k<res) res=k;
        return true;
    }
    int ms=INF, cur=0;
    for(int t=r[head]; t!=head; t=r[t])
        if(s[t]<ms)
        {
            ms=s[t];
            cur=t;
        }
    for(int i=d[cur]; i!=cur; i=d[i])
    {
//        int rr = (row[i] - 1) / 2 + 1;
//        if (!use[rr]) use[rr] = true;
//        else continue;
        remove(i);
        for(int j=r[i]; j!=i; j=r[j])
        {
            remove(j);
            s[c[j]]--;
        }
        dfs(k+1);
        for(int j=l[i]; j!=i; j=l[j])
        {
            resume(j);
            s[c[j]]++;
        }
//        use[rr] = false;
        resume(i);
    }
    return false;
}
const int N=10;
int stick[2*N*(N+1)+N][N*N];/*
void makestick(int n)
{
     for (int i=1;i<=2*n*(n+1);++i)
     {
         if (i<=n) 
         {
            stick[i][0]=1;
            stick[i][1]=i;
         }
         else if (i>=2*n*(n+1)-n+1)
         {
               stick[i][0]=1;
               stick[i][1]=n*n-2*n*(n+1)+i;
         }
         else if (i % (2*n+1)==n+1)
         {
               stick[i][0]=1;
               stick[i][1]=((i)/(2*n+1))*n+1;
         }
         else if (i % (2*n+1)==0)
         {
               stick[i][0]=1;
               stick[i][1]=(i/(2*n+1))*n;
         }
         
         else if (i % (2*n+1)>n+1)
         {
              stick[i][0]=2;
              stick[i][1]=(i/(2*n+1))*n+i%(2*n+1)-n-1;
              stick[i][2]=(i/(2*n+1))*n+i%(2*n+1)-n;
         }
         else
         {
             stick[i][0]=2;
             stick[i][1]=(i/(2*n+1)-1)*n+i%(2*n+1);
             stick[i][2]=(i/(2*n+1)-1)*n+i%(2*n+1)+n;
         }
     }/*
     for (int i=1;i<=2*n*(n+1);++i)
     {
         printf("%d--%d:",i,stick[i][0]);
         for (int j=1;j<=stick[i][0];++j)
             printf(" %d",stick[i][j]);
         printf("\n");
     }
}
*/
int NumOfSq;
void makestick(int n)
{
     memset(stick,0,sizeof(stick));
     NumOfSq=0;int ss;
     for (int c=1;c<=n;++c)
     {
         for (int i=1;i<=n-c+1;++i)
         {
             for (int j=1;j<=n-c+1;++j)
             {
                 ++NumOfSq;
                 
                 //Up
                 ss=(i-1)*(2*n+1)+j;
                 for (int p=0;p<c;++p)
                 {
                     ++stick[ss+p][0];
                     stick[ss+p][stick[ss+p][0]]=NumOfSq;
                 }
                 
                 //Left
                 ss=(i-1)*(2*n+1)+j+n;
                 for (int p=0;p<c;++p)
                 {
                     stick[ss+p*(2*n+1)][++stick[ss+p*(2*n+1)][0]]=NumOfSq;
                 }
                 
                 //Right
                 ss=(i-1)*(2*n+1)+j+c+n;
                 for (int p=0;p<c;++p)
                 {
                     stick[ss+p*(2*n+1)][++stick[ss+p*(2*n+1)][0]]=NumOfSq;
                 }
                 
                 //Down
                 ss=(i-1+c)*(2*n+1)+j;
                 for (int p=0;p<c;++p)
                 {
                     stick[ss+p][++stick[ss+p][0]]=NumOfSq;
                 }
             }
         }
     }
     /*
     for (int i=1;i<=2*n*(n+1);++i)
     {
         printf("%d--%d:",i,stick[i][0]);
         for (int j=1;j<=stick[i][0];++j)
             printf(" %d",stick[i][j]);
         printf("\n");
     }
     */
}
int n,m,M;
bool lstsq[N*N*2+N];
bool lststick[2*N*(N+1)+N];
int sq[N*N*2+N];
int sqnum[N*N*2+N];
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
          memset(sqnum,0,sizeof(sqnum));
          memset(mat,0,sizeof(mat));
          memset(lstsq,0,sizeof(lstsq));
          memset(lststick,0,sizeof(lststick));
          memset(sq,0,sizeof(sq));
          scanf("%d%d",&n,&m);
          makestick(n);
          int rline;
          while (m--)
          {
                int st;
                scanf("%d",&st);
                lststick[st]=1;
                for (int i=1;i<=stick[st][0];++i)
                    lstsq[stick[st][i]]=1;
                
          } 
          sq[0]=0; 
          for (int i=1;i<=NumOfSq;++i)
          {
                    if (lstsq[i]) continue;
                    ++sq[0];
                    sq[sq[0]]=i;
                    sqnum[i]=sq[0];
          }    
                rline=0;
                for (int i=1;i<=2*n*(n+1);++i)
                {
                    if (lststick[i]) continue;
                    ++rline;
                    for (int j=1;j<=stick[i][0];++j)
                    {
                        if (lstsq[stick[i][j]]) continue;
                        mat[rline][sqnum[stick[i][j]]]=1;
                    }
                }
          
          initial(rline,sq[0]);
          dfs(0);
          printf("%d\n",res);
    }
}


 

 

分而治之-系统复杂度的解决之道

-
  • 1970年01月01日 08:00

poj1084(求逆序数)

题意:给一个长度为n的序列,每次交换相邻的元素,求最少的交换次数。也就是求冒泡排序的交换次数。 解题思路:对于冒泡排序,每一次相邻交换,那么这个序列的逆序数减1,当这个序列有序是,逆序数就为0。我们...
  • u013509299
  • u013509299
  • 2014-09-04 21:24:13
  • 640

poj 1084

dlx... 万万没想到可以用Dlx搞。。。 对于任意一个正方形,我们都至少要拿掉其中的一个火柴,于是如果构造一个行表示火柴、列表示正方形的矩阵,如果第i根火柴属于第j个正方形,那么g[i][j]...
  • ACpac
  • ACpac
  • 2014-08-26 11:13:00
  • 314

POJ1084 DLX 摧毁火柴棒

#include #include #include #include #include #include #include #include #include #include ...
  • u011535421
  • u011535421
  • 2017-09-30 05:42:20
  • 90

POJ 1084 搜索(IDA*)

题意:给一个由(n+1)*n*2根火柴棒构成的边长为n正方形,每根火柴棒都有编号,已经删去了k根火柴棒,问至少再删多少根火柴棒可以破坏掉所有正方形。 【刘汝佳:《算法竞赛入门经典(第二版)》 P21...
  • qq_25978793
  • qq_25978793
  • 2015-10-13 08:57:47
  • 767

POJ1084-重复覆盖,DLX

这题可理解为用最少用多少火柴棒覆盖全部的正方形,以正方形为列,火柴棒为行,重复覆盖模型明显。 建图的时候要找出所有正方形所包含的火柴棒,我是这样找的: 先确定最左上边的正方形(边长为1~n)所包含...
  • yihuikang
  • yihuikang
  • 2012-08-20 12:45:35
  • 1641

【POJ1084】Square Destroyer 重复覆盖问题 DLX(Dancing Links)

这么赞的重复覆盖问题DLX版题解还去哪找?菜鸟和老鸟都来看看。
  • Vmurder
  • Vmurder
  • 2014-10-29 22:50:29
  • 1909

POJ 1084 Square Destroyer【Dancing Links重复覆盖】

Square Destroyer Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2695 ...
  • ahfywff
  • ahfywff
  • 2012-09-04 14:27:39
  • 2005

poj 1084 Square Destroyer

  • 2017年05月27日 14:40
  • 3KB
  • 下载

【POJ 1084】 很烦人的DLX

DLX。。。 一开始读错题目了。。。是要把所有正方形都消掉!!! 代码里面有两种统计正方形和火柴的方法,都值得借鉴。。Orz 发一下代码   #include ...
  • buaa_kiss
  • buaa_kiss
  • 2011-10-14 20:02:31
  • 982
收藏助手
不良信息举报
您举报文章:【POJ 1084】 很烦人的DLX
举报原因:
原因补充:

(最多只允许输入30个字)