• 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
  • 相关阅读:
    C++ Primer Plus 第15章 友元、异常和其它
    03013_JDBC工具类
    python GUI编程(Tkinter)
    Python2.x与3​​.x版本区别
    【python教程】Python JSON
    【python教程】Python IDE
    通过Google Custom Search API 进行站内搜索
    支持wmv、mpg、mov、avi格式的网页视频播放代码
    编写更好的jQuery代码的建议
    KindEditor得不到textarea值的解决方法
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4836841.html
Copyright © 2020-2023  润新知