Uva 11694 Gokigen Naname

基本思路是Dfs:

  1. 一个一个格子摆放,以每个各自的左上角的点为基准点代表格子,比如(0,0)代表(0,0)(0,1)(1,0)(1,1)组成的格子,(0,1)代表(0,1)(0,2)(1,1),(1,2)组成的格子,以此类推,即可一个一个格子按顺序摆放。

  2. 当摆放(x,y)时,比较分别放 \ 和放 / ,同时比较(x,y)的数值要求是否已经达到(不能多不能少,(x,y)必须刚好达到),其次比较另外的如(x+1,y),(x+1,y+1),(x,

y+1)是否已经超出要求。再者就是判断是否构成环,我采用了dfs的方法。

  3. 如何表示这个点连接几条斜线了呢?可以用一个数组保存,如point[i][j] 表示(i, j)连接了point[i][j]条斜线。而判断两个点是否连接可以用link[][][][],如link[a][b][c][d],表示link[a][b][c][d]是否连接。

 

  一点收获与感悟:最初写的时候,没有link数组,想用point[a][b]和point[c][d]是否同时大于1判断(a, b)与(c,d)是否连接,结果可想而知,这个错误明显了!发现这个错误后才加入了link数组。但这样只是解决了错误,还没有解决超时。刚开始写的时候只判断了(x,y)是否满足要求,没有判断其它点,后来一想,可能再给(x, y)(x+1, y+1)相连时,(x+1, y+1)连接的边数就超过(x+1, y+1)要求的边数了,所以要同时判断与(x,y)相连的点,这个判断一添,就没有超时了。

 

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 7 + 3;
char chess[MAXN][MAXN];
int point[MAXN][MAXN];
bool link[MAXN][MAXN][MAXN][MAXN];
int N;
int go[4][2] = {1,1, 1,-1,  -1,-1, -1,1};

void Read() {
    for(int i=0; i<N+1; ++ i) {
        for(int j=0; j<N+1; ++ j) {
            cin >> chess[i][j];
        }
    }
}

bool vis[MAXN][MAXN];
bool found;

void Loop(int x, int y, int a, int b) {
    if(found || x<0 || x>N || y<0 || y>N || !link[x][y][a][b] ) {
        return ;
    }
    if(vis[x][y]) {
        found = true;
        return ;
    }
    vis[x][y] = true;
    for(int i=0; i<4; ++i) {    
        if( x+go[i][0]!=a || y+go[i][1]!=b ) {
            Loop(x+go[i][0], y+go[i][1], x, y);
        }
    }
}

bool Any(int x, int y) {
    memset(vis, false, sizeof(vis));
    found = false;
    vis[x][y] = true;
    Loop(x+1, y+1, x, y);
    Loop(x-1, y-1, x, y);
    Loop(x-1, y+1, x, y);
    Loop(x+1, y-1, x, y);
    return !found;
}

bool Dfs(int r, int c) {
    if(c == N) {
        if( isdigit(chess[r][c]) && point[r][c] != chess[r][c] - '0') {
            return false;
        }
        ++ r; c = 0;
        if(r == N) {
            for(int i=0; i<N+1;i++) {
                if(isdigit(chess[r][i]) && point[r][i] != chess[r][i] - '0') {
                    return false;
                }
            }
            return true;
        } else {
            return Dfs(r, c);
        }
    }
    int x = r, y = c;
    point[x][y] ++;
    point[x+1][y+1] ++;
    link[x][y][x+1][y+1] = true;
    link[x+1][y+1][x][y] = true;
    if( isdigit(chess[x][y]) && point[x][y] != chess[x][y] - '0') {
        ;
    } else if(isdigit(chess[x+1][y+1]) && point[x+1][y+1] > chess[x+1][y+1] - '0') {
        ;
    } else if(Any(x, y)) {
        ++ y;
        if(Dfs(x, y)) {
            return true;
        }
    }
    x = r, y =c;
    link[x][y][x+1][y+1] = false;
    link[x+1][y+1][x][y] = false;
    point[x][y] --;
    point[x+1][y+1] --;

    point[x][y+1] ++;
    point[x+1][y] ++;
    link[x][y+1][x+1][y] = true;
    link[x+1][y][x][y+1] = true;
    if( isdigit(chess[x][y]) && point[x][y] != chess[x][y] - '0') {
        ;
    } else if(isdigit(chess[x][y+1]) && point[x][y+1] > chess[x][y+1] - '0') {
        ;
    } else if(isdigit(chess[x+1][y]) && point[x+1][y] > chess[x+1][y] - '0') {
        ;
    } else if(Any(x, y+1)) {
        ++ y;
        if(Dfs(x, y)) {
            return true;
        }
    }
    x = r, y =c;
    link[x][y+1][x+1][y] = false;
    link[x+1][y][x][y+1] = false;
    point[x][y+1] --;
    point[x+1][y] --;
    return false;
}

void Work() {
    memset(point, 0, sizeof(point));
    memset(link, false, sizeof(link));
    Dfs(0 ,0);
}

void Print() {
    for(int i=0; i<N; ++i) {
        for(int j=0; j<N; ++j) {
            if(point[i][j] && point[i+1][j+1] && link[i][j][i+1][j+1]) {
                cout << "\\";
            } else {
                cout << "/";
            }
        }
        cout << endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin >> T;
    while(T --) {
            cin >> N;
            Read();
            Work();
            Print();
    }
    return 0;
}

 

posted @ 2015-08-13 14:44  Emerald  阅读(625)  评论(0编辑  收藏  举报