15145641

  这个题目的深搜形式,我也找出来了,dfs(i,j)表示第i个人选到了第j个物品,但是我却无限RE了,原因是我的viod型深搜太过暴力,我当时定义了一个计数器,来记录并限制递归的层数,发现它已经递归到了1500层,加上限制后,WA了……后来学习了网上的方法,使用bool型的深搜,每一次选择都去跟题目中给的限制去比较,看这次选择有没有冲突,如果没有搜下一个,当搜到false的时候,及时停止,节省了时间和空间。

  伪代码: if(dfs(next)==true) return true; else return false; 这样我们在很有可能在选某一个数的时候,发现已经没有合适方案,及时停止递归,而不是我那种每次都递归到最底层。

  注意:我的代码比较短,但是耗时83MS,源代码很长,耗时3MS,区别是判断冲突的方法不一样,读者可以自己思考其他的判定方法,应该还有很多。

  再就是我的做了一步优化,我们可以从第二个物品开始选,这样也保证了题目的输出正确。

  最后,UVAlive的oj好奇葩,我自己的代码WA时,还感觉很奇怪,后来发现少了换行,它怎么就是不返回PE呢……被坑好多次……

  代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define N 10
struct Check{
    int a,b,c,d;
    char op[2];
}ch[2500];
char maps[N][N];
int n,m,cnt,belong[N][N];
bool dfs(int ci,int cj){
    int a,b,c,d,flag;
    char op;
    if(ci==m+1 && cj == 2){
        return true;
    }
    for(int i = 1;i <= m;i++){
        if(belong[cj][i]) continue;
        belong[cj][i] = ci;
        flag = 1;
        for(int j = 0;j < cnt;j++){
            a = ch[j].a; b = ch[j].b;
            c = ch[j].c; d = ch[j].d;
            op = ch[j].op[0];
            if((!belong[a][b]) || (!belong[c][d])) continue;
            if(op=='R'&&belong[a][b] != belong[c][d]){
                flag = 0;
                break;
            }
            if(op=='N'&&belong[a][b] == belong[c][d]){
                flag = 0;
                break;
            }
        }
        if(!flag){
            belong[cj][i] = 0;
            continue;
        }
        if(cj==n){
            if(dfs(ci+1,2)) return true;
        }
        else if(dfs(ci,cj+1)) return true;
        belong[cj][i] = 0;
    }
    return false;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++){
            scanf("%s",maps[i]+1);
        }
        for(cnt = 0;true;cnt++){
            scanf("%d%d%s%d%d",&ch[cnt].a,&ch[cnt].b,ch[cnt].op,&ch[cnt].c,&ch[cnt].d);
            if(ch[cnt].a == 0){
                break;
            }
        }
        memset(belong,0,sizeof(belong));
        for(int i = 1;i <= m;i++) belong[1][i] = i;
        dfs(1,2);
        for(int i = 1;i <= m;i++){
            for(int j = 1;j <= n;j++){
                for(int k = 1;k <= m;k++){
                    if(belong[j][k]==i){
                        printf("%c",maps[j][k]);
                    }
                }
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

 

posted on 2016-07-24 17:13  icode-xiaohu  阅读(253)  评论(0编辑  收藏  举报