1048. Inverso

翻牌,将所翻牌地所有相邻的排都翻一遍。

说明:1.翻两次回恢复原状。所以结果中没有重复数字。

            2.所得结果和翻牌次序无关 如 121 <->211 <->2

            3.初始即为全白www。。。,则要输出11;

            

            4.我用一个整数保存的路径,因为结果最大为123456789

          

         所以广度优先搜索,2^9   时间和空间复杂度大致均1024次内,所以也不用什么位操作什么的,直接就可以了。

        我的疑问是为什么深度优先搜不行?一直wa,如果按照顺序1-9的搜,应该也是对的呀?

下附bfs ac的:


#include<stdio.h>
#include<cstring>
#include<queue>
using namespace std;

int N;
char s[10] , cp[10] , goal[10] = "wwwwwwwww";
int v[1025];

void opp(char & c){
    if(c == 'w') c = 'b';
    else if( c == 'b') c= 'w';
}
struct PAIR{
    int rou;
    char str[10];
};
queue<PAIR> q;

int toInt(){
    int i = 0;
    for(int k = 0; k < 9;k++)
        i = i * 2 + ((s[k] == 'w') ? 1 : 0); 
    return i;
}
void invert(int i){
    int k;
    switch(i){
    case 1: opp(s[0]);opp(s[1]);opp(s[3]);opp(s[4]);break;
    case 2: for( k = 0; k < 6; k++) opp(s[k]);break;
    case 3: opp(s[1]);opp(s[2]);opp(s[4]);opp(s[5]);break;
    case 4: for( k = 0; k<7 ; k+=3)opp(s[k]);
            for( k = 1; k<8 ; k+=3)opp(s[k]);break;
    case 5: for( k = 0; k<9; k++)opp(s[k]);break;
    case 6: for( k = 1; k<8 ; k+=3)opp(s[k]);
            for( k = 2; k<9 ; k+=3)opp(s[k]);break;
    case 7: opp(s[3]);opp(s[4]);opp(s[6]);opp(s[7]);break;
    case 8: for( k = 3; k<9 ; k++)opp(s[k]);break;
    case 9: opp(s[4]);opp(s[5]);opp(s[7]);opp(s[8]);break;
    default: break;
    }
}


int main(){

       //freopen("in.txt", "r", stdin);
       scanf("%d", &N);
       while(N--){
           while(!q.empty())q.pop();
            scanf("%s", s);
            memset(v, 0, sizeof(v));
            int i , start, road = 11;
            PAIR pr;
            pr.rou  = 0;
            strcpy(pr.str , s);
            q.push(pr);
            while(!q.empty() && strcmp(s, goal)){
                start = q.front().rou ;
                strcpy(s, q.front().str);
                q.pop();
                for(i = start % 10 + 1; i<10; i++){
                     invert( i );
                     int tmp = toInt( );
                     if(v[tmp]){invert(i) ;continue;}
                     v[tmp] = 1;
                     pr.rou = start * 10 + i;
                     strcpy(pr.str , s);
                     q.push(pr);
                     if(! strcmp(s, goal)){road = pr.rou;break;}
                     invert(i);
                     
                }
            }
            printf("%d\n", road);
        
       }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值