zoukankan      html  css  js  c++  java
  • UVALive 2659+HUST 1017+ZOJ 3209+FZU 1686 (DLX

    UVALive 2659

    题目:16*16的数独.试了一发大白模板.

    /*
    * @author:  Cwind
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-6)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define INF (1000000000)
    #define FINF (1e3)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    const int maxr = 5000;
    const int maxn = 2000;
    const int maxnode = 20000;
    
    struct DLX {
        int n, sz;
        int S[maxn];
    
        int row[maxnode], col[maxnode];
        int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
    
        int ansd, ans[maxr];
    
        void init(int n) {
            this->n = n;
    
            for(int i = 0 ; i <= n; i++) {
                U[i] = i; D[i] = i; L[i] = i-1, R[i] = i+1;
            }
            R[n] = 0; L[0] = n;
    
            sz = n + 1;
            memset(S, 0, sizeof(S));
        }
    
        void addRow(int r, vector<int> &columns) {
            int first = sz;
            for(int i = 0; i < columns.size(); i++) {
                int c = columns[i];
                L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c];
                D[U[c]] = sz; U[c] = sz;
                row[sz] = r; col[sz] = c;
                S[c]++; sz++;
            }
            R[sz - 1] = first; L[first] = sz - 1;
        }
    
        #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) 
    
        void remove(int c) {
            L[R[c]] = L[c];
            R[L[c]] = R[c];
            FOR(i,D,c)
            FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; }
        }
    
        void restore(int c) {
            FOR(i,U,c)
            FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; }
            L[R[c]] = c;
            R[L[c]] = c;
        }
    
        bool dfs(int d) {
            if (R[0] == 0) {
                ansd = d;
                return true;
            }
    
            int c = R[0]; 
            FOR(i,R,0) if(S[i] < S[c]) c = i;
    
            remove(c);
            FOR(i,D,c) {
                ans[d] = row[i];
                FOR(j,R,i) remove(col[j]);
                if(dfs(d+1)) return true;
                FOR(j,L,i) restore(col[j]);
            }
            restore(c);
    
            return false;
        }
    
        bool solve(vector<int>& v) {
            v.clear();
            if(!dfs(0)) return false;
            for(int i = 0; i < ansd; i++) v.push_back(ans[i]);
                return true;
        }
    
    }solver;
    
    const int SLOT=0;
    const int ROW=1;
    const int COL=2;
    const int SUB=3;
    
    int encode(int a,int b,int c){
        return a*256+b*16+c+1;
    }
    
    char puzzal[20][20];
    
    void decode(vector<int> &ans){
        for(int i=0;i<ans.size();i++){
            ans[i]--;
            int c=ans[i]%16;ans[i]/=16;
            int b=ans[i]%16;ans[i]/=16;
            int a=ans[i];
            puzzal[a][b]='A'+c;
        }
    }
    bool flag=0;
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        //freopen("test.in","r",stdin);
        //freopen("test.out","w",stdout);
        while(scanf("%s",puzzal[0])!=EOF){
            for(int i=1;i<16;i++){
                scanf("%s",puzzal[i]);
            }
            if(flag){
                puts("");
            }else{
                flag=1;
            }
            solver.init(1024);
            for(int r=0;r<16;r++){
                for(int c=0;c<16;c++){
                    for(int v=0;v<16;v++){
                        if(puzzal[r][c]=='-'||puzzal[r][c]=='A'+v){
                            vector<int> columns;
                            columns.pb(encode(SLOT,r,c));
                            columns.pb(encode(ROW,r,v));
                            columns.pb(encode(COL,c,v));
                            columns.pb(encode(SUB,r/4*4+c/4,v));
                            solver.addRow(encode(r,c,v),columns);
                        }
                    }
                }
            }
            vector<int> ans;
            solver.solve(ans);
            decode(ans);
            for(int i=0;i<16;i++){
                for(int j=0;j<16;j++){
                    printf("%c",puzzal[i][j]);
                }
                puts("");
            }
        }
        return 0;
    }
    View Code

     HUST 1017

    题目:裸精确覆盖,继续套模板.

    /*
    * @author:  Cwind
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-6)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define INF (1000000000)
    #define FINF (1e3)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    const int maxr = 5000;
    const int maxn = 2000;
    const int maxnode = 1e6+3000;
    
    struct DLX {
        int n, sz;
        int S[maxn];
    
        int row[maxnode], col[maxnode];
        int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
    
        int ansd, ans[maxr];
    
        void init(int n) {
            this->n = n;
    
            for(int i = 0 ; i <= n; i++) {
                U[i] = i; D[i] = i; L[i] = i-1, R[i] = i+1;
            }
            R[n] = 0; L[0] = n;
    
            sz = n + 1;
            memset(S, 0, sizeof(S));
        }
    
        void addRow(int r, vector<int> &columns) {
            int first = sz;
            for(int i = 0; i < columns.size(); i++) {
                int c = columns[i];
                L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c];
                D[U[c]] = sz; U[c] = sz;
                row[sz] = r; col[sz] = c;
                S[c]++; sz++;
            }
            R[sz - 1] = first; L[first] = sz - 1;
        }
    
        #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) 
    
        void remove(int c) {
            L[R[c]] = L[c];
            R[L[c]] = R[c];
            FOR(i,D,c)
            FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; }
        }
    
        void restore(int c) {
            FOR(i,U,c)
            FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; }
            L[R[c]] = c;
            R[L[c]] = c;
        }
    
        bool dfs(int d) {
            if (R[0] == 0) {
                ansd = d;
                return true;
            }
    
            int c = R[0]; 
            FOR(i,R,0) if(S[i] < S[c]) c = i;
    
            remove(c);
            FOR(i,D,c) {
                ans[d] = row[i];
                FOR(j,R,i) remove(col[j]);
                if(dfs(d+1)) return true;
                FOR(j,L,i) restore(col[j]);
            }
            restore(c);
    
            return false;
        }
    
        bool solve(vector<int>& v) {
            v.clear();
            if(!dfs(0)) return false;
            for(int i = 0; i < ansd; i++) v.push_back(ans[i]);
                return true;
        }
    
    }solver;
    
    int n,m;
    vector<int> columns;
    vector<int> ans;
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        //freopen("test.in","r",stdin);
        //freopen("test.out","w",stdout);
        while(cin>>n>>m){
            solver.init(m);
            for(int r=1;r<=n;r++){
                columns.clear();
                int x;
                scanf("%d",&x);
                for(int j=0;j<x;j++){
                    int v;
                    scanf("%d",&v);
                    columns.pb(v);
                }
                solver.addRow(r,columns);
            }
            ans.clear();
            bool f=solver.solve(ans);
            if(!f){
                puts("NO");
                continue;
            }
            printf("%d",(int)ans.size());
            for(int i=0;i<ans.size();i++){
                printf(" %d",ans[i]);
            }
            puts("");
        }
        return 0;
    }
    View Code

     ZOJ 3209

    题目:给出一张地图的若干个碎片,要求用最少的碎片恢复原地图.

    思路:基本还是裸的dlx,搜的时候剪枝一下就好.

    /*
    * @author:  Cwind
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-6)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define INF (1000000000)
    #define FINF (1e3)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    const int maxr = 5000;
    const int maxn = 2000;
    const int maxnode = 1e6+3000;
    
    struct DLX {
        int n, sz;
        int S[maxn];
    
        int row[maxnode], col[maxnode];
        int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
    
        int ansd, ans[maxr];
    
        void init(int n) {
            this->n = n;
    
            for(int i = 0 ; i <= n; i++) {
                U[i] = i; D[i] = i; L[i] = i-1, R[i] = i+1;
            }
            R[n] = 0; L[0] = n;
    
            sz = n + 1;
            memset(S, 0, sizeof(S));
        }
    
        void addRow(int r, vector<int> &columns) {
            int first = sz;
            for(int i = 0; i < columns.size(); i++) {
                int c = columns[i];
                L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c];
                D[U[c]] = sz; U[c] = sz;
                row[sz] = r; col[sz] = c;
                S[c]++; sz++;
            }
            R[sz - 1] = first; L[first] = sz - 1;
        }
    
        #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) 
    
        void remove(int c) {
            L[R[c]] = L[c];
            R[L[c]] = R[c];
            FOR(i,D,c)
            FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; }
        }
    
        void restore(int c) {
            FOR(i,U,c)
            FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; }
            L[R[c]] = c;
            R[L[c]] = c;
        }
    
        void dfs(int d) {
            if(ansd!=-1&&d>ansd) return;
            if (R[0] == 0) {
                if(ansd==-1)
                    ansd = d;
                else
                    ansd=min(ansd,d);
                return;
            }
            int c = R[0]; 
            FOR(i,R,0) if(S[i] < S[c]) c = i;
    
            remove(c);
            FOR(i,D,c) {
                ans[d] = row[i];
                FOR(j,R,i) remove(col[j]);
                dfs(d+1);
                FOR(j,L,i) restore(col[j]);
            }
            restore(c);
            return;
        }
    
        void solve(vector<int>& v) {
            v.clear();
            dfs(0);
            for(int i = 0; i < ansd; i++) v.push_back(ans[i]);
        }
    
    }solver;
    
    int T,n,m,p;
    vector<int> columns;
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        //freopen("test.in","r",stdin);
        //freopen("test.out","w",stdout);
        cin>>T;
        while(T--){
            cin>>n>>m>>p;
            solver.init(n*m);
            for(int r=1;r<=p;r++){
                int x1,y1,x2,y2;
                columns.clear();
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                x1++,y1++;
                for(int i=x1;i<=x2;i++){
                    for(int j=y1;j<=y2;j++){
                        columns.pb((i-1)*m+j);
                    }
                }
                solver.addRow(r,columns);
            }
            solver.ansd=-1;
            solver.dfs(0);
            printf("%d
    ",solver.ansd);
        }
        return 0;
    }
    View Code

     FZU 1686

    题目;每次可以攻击一个矩形子矩阵,问最少攻击多少次达到目标.

    思路:可重复覆盖的DLX和精确覆盖版的主要有这么几个区别

    1)删除的时候,精确覆盖要求删去所有当前行已经覆盖的列,以及在已覆盖列上还有元素的所有行,而可重复覆盖只是删除已经覆盖的所有列.

    2)由于可重复覆盖通常要求解最小步数,所以需要一个剪枝.

    /*
    * @author:  Cwind
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-6)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    //#define INF (1000000000)
    #define FINF (1e3)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    
    const int MaxM = 15*15+10;//width
    const int MaxN = 15*15+10;//hight
    const int maxnode = MaxN * MaxM;
    const int INF = 0x3f3f3f3f;
    struct DLX{
        int n,m,size;
        int
        U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
        int H[MaxN],S[MaxM];
    
        int ansd;
        void init(int _n,int _m){
            n = _n;
            m = _m;
            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;
            size = m;
            for(int i = 1;i <= n;i++)
                H[i] = -1;
        }
        void Link(int r,int c){
            ++S[Col[++size]=c];
            Row[size] = r;
            D[size] = D[c];
            U[D[c]] = size;
            U[size] = c;
            D[c] = size;
            if(H[r] < 0)H[r] = L[size] = R[size] = size;
            else{
                R[size] = R[H[r]];
                L[R[H[r]]] = size;
                L[size] = H[r];
                R[H[r]] = size;
            }
        }
        void remove(int c){
            for(int i = D[c];i != c;i = D[i])
                L[R[i]] = L[i], R[L[i]] = R[i];
        }
        void resume(int c){
            for(int i = U[c];i != c;i = U[i])
                L[R[i]] = R[L[i]] = i;
        }
        bool v[MaxM];
        int f(){
            int ret = 0;
            for(int c = R[0]; c != 0;c = R[c])
                v[c] = true;
            for(int c = R[0]; c != 0;c = R[c]){
                if(v[c]){
                    ret++;
                    v[c] = false;
                    for(int i = D[c];i != c;i = D[i]){
                        for(int j = R[i];j != i;j = R[j])
                            v[Col[j]] = false;
                    }
                }
            }
            return ret;
        }
        void Dance(int d=0){
            if(d + f() >= ansd)return;
            if(R[0] == 0){
                if(d < ansd)ansd = d;
                return;
            }
            int c = R[0];
            for(int i = R[0];i != 0;i = R[i]){
                if(S[i] < S[c])
                    c = i;
            }
            for(int i = D[c];i != c;i = D[i]){
                remove(i);
                for(int j = R[i];j != i;j = R[j])remove(j);
                    Dance(d+1);
                for(int j = L[i];j != i;j = L[j])resume(j);
                    resume(i);
            }
        }
    }dan;
    
    int n,m;
    int grid[20][20];
    int id[20][20];
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        //freopen("test.in","r",stdin);
        //freopen("test.out","w",stdout);
        while(cin>>n>>m){
            int sz=1;
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    scanf("%d",&grid[i][j]);
                    if(grid[i][j]) id[i][j]=sz++;
                }
            }
            dan.init(n*m,sz-1);
            int n1,m1;
            scanf("%d%d",&n1,&m1);
            sz=1;
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    for(int x=0;x<n1;x++){
                        for(int y=0;y<m1;y++){
                            if(i+x<n&&j+y<m&&grid[i+x][j+y]){
                                dan.Link(sz,id[i+x][j+y]);
                            }
                        }
                    }
                    sz++;
                }
            }
            dan.ansd=INF;
            dan.Dance();
            printf("%d
    ",dan.ansd);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4836841.html
Copyright © 2011-2022 走看看