zoukankan      html  css  js  c++  java
  • FZU1686 神龙的难题 dancing links 重复覆盖

    分析:每次可以打一个小矩阵的怪,然后把每个怪看成一列,然后每个小矩阵看成一行,枚举左上角就行

    注:然后注意总共的节点数是新图的行*列的个数,不是原图

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=230*230;
    const double eps=1e-8;
    int n,m,sz,k;
    int u[N],l[N],r[N],d[N];
    int h[230],s[230],col[N];
    void init()
    {
        for(int i=0; i<=m; ++i)
        {
            s[i]=0;
            u[i]=d[i]=i;
            l[i]=i-1;
            r[i]=i+1;
        }
        r[m]=0;
        l[0]=m;
        sz=m;
        for(int i=1; i<=n; ++i)
            h[i]=-1;
    }
    void link(int x,int y)
    {
        ++sz;
        ++s[y],col[sz]=y;
        u[sz]=u[y],d[u[y]]=sz;
        d[sz]=y,u[y]=sz;
        if(h[x]==-1)h[x]=l[sz]=r[sz]=sz;
        {
            l[sz]=l[h[x]];
            r[l[h[x]]]=sz;
            r[sz]=h[x];
            l[h[x]]=sz;
        }
    }
    void del(int y)
    {
        for(int i=d[y]; i!=y; i=d[i])
            r[l[i]]=r[i],l[r[i]]=l[i];
    }
    void resume(int y)
    {
        for(int i=d[y]; i!=y; i=d[i])
            r[l[i]]=l[r[i]]=i;
    }
    bool vis[230];
    int f()
    {
        int ret=0;
        for(int i=r[0]; i; i=r[i])
            vis[i]=0;
        for(int i=r[0]; i; i=r[i])
        {
            if(vis[i])continue;
            vis[i]=1;
            ++ret;
            for(int j=d[i]; j!=i; j=d[j])
                for(int k=r[j]; k!=j; k=r[k])
                    vis[col[k]]=1;
        }
        return ret;
    }
    int ans;
    void dance(int pos)
    {
        if(pos+f()>=ans)return;
        if(!r[0])
        {
            ans=min(pos,ans);
            return;
        }
        int t=r[0];
        for(int i=r[0]; i!=0; i=r[i])
            if(s[i]<s[t])t=i;
        for(int i=d[t]; i!=t; i=d[i])
        {
            del(i);
            for(int j=r[i]; j!=i; j=r[j])
                del(j);
            dance(pos+1);
            for(int j=l[i]; j!=i; j=l[j])
                resume(j);
            resume(i);
        }
    }
    int mp[20][20];
    int main()
    {
        int n1,m1;
        while(~scanf("%d%d",&n,&m))
        {
            int cnt=0,tot=0;
            for(int i=1; i<=n; ++i)
                for(int j=1; j<=m; ++j)
                  {
                      scanf("%d",&mp[i][j]);
                      if(mp[i][j]==1)mp[i][j]=++cnt;
                  }
            scanf("%d%d",&n1,&m1);
            int tmp=(n-n1+1)*(m-m1+1);
            swap(n,tmp),swap(m,cnt);
            init();
            swap(n,tmp),swap(m,cnt);
            for(int i=1;n-i+1>=n1;++i)
            {
               for(int j=1;m-j+1>=m1;++j)
               {
                  ++tot;
                  for(int x=i;x<i+n1;++x)
                   for(int y=j;y<j+m1;++y)
                    if(mp[x][y]!=0)link(tot,mp[x][y]);
               }
            }
            ans=230;
            dance(0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    cookie写入,读取,删除
    javascript模板
    javascript思维导图
    html+css
    Google Java编程风格指南
    mysql1449 The user specified as a definer ('root'@'%') does not exist 解决方法
    mongoDB非正常关闭后无法启动问题
    Android应用程序注册广播接收器(registerReceiver)的过程分析
    Android应用程序在新的进程中启动新的Activity的方法和过程分析
    Android系统中的广播(Broadcast)机制简要介绍和学习计划
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5289896.html
Copyright © 2011-2022 走看看