码迷,mamicode.com
首页 > 其他好文 > 详细

UVALive 2659+HUST 1017+ZOJ 3209 (DLX

时间:2015-09-25 00:02:54      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

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\n",solver.ansd);
    }
    return 0;
}
View Code

 

UVALive 2659+HUST 1017+ZOJ 3209 (DLX

标签:

原文地址:http://www.cnblogs.com/Cw-trip/p/4836841.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!