UVa 10651 Pebble Solitaire (DFS)

题目:有一些格子,这些格子都是挨着的,并排摆放的,有的格子里面有石子,有的没有,当满足一下条件的时候,就会做一下的操作:

          条件:用1表示有格子,0表示没有。如果连续的三个格子的状态是011,就把它给成100, 相当于将最后边的1放到最左边,然后去掉中间的那个1;如果是110,就改成001,即将最左的1放大最右,然后去掉中间的那个。

分析:

还是搜索。

这道题,一共只有12个格子,从数据上来讲,dfs是没有问题的。

其次,位运算压缩状态,记录已经遍历过的状态。

最后就是用位运算判断有无石子,若满足条件,就修改值。

取反就和1做异或运算,判断就和1做与运算。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = ( (1<<12) + 10 );
bool vis[N];
int n, now, ans, snum, dl, tmp;
char data[15];

void dfs( int state, int x ) {
    vis[state] = true;
    if ( x > ans ) ans = x;
    for ( int i = 0; i < dl-2; ++i ) {
        int s1 = ( 1 << ( dl-i-1 ) ), s2 = ( 1 << ( dl-i-2 ) ), s3 = ( 1 << ( dl-i-3 ) );
      //cout << s1 << " " << s2 << " " << s3 << endl;
        if ( (state & s1) == 0 ) {
            if ( (state & s2) > 0 && (state & s3) > 0 ) {
               //cout << state << endl;
                tmp = state ^ s3 ^ s2 ^ s1;
               //cout << tmp << endl;
                if ( !vis[tmp] ) dfs( tmp, x+1 );
            }
        }
        else {
            if ( (state & s2) > 0 && (state & s3) == 0 ) {
                tmp = state ^ s1 ^ s2 ^ s3;
               //cout << tmp << endl;
                if ( !vis[tmp] ) dfs( tmp, x+1 );
            }
        }
    }
}
int main()
{
    scanf("%d", &n);
    getchar();
    while( n-- ) {
        scanf("%s", data);
        now = ans = snum = 0;
        memset(vis, 0, sizeof(vis));
        dl = strlen(data);
        for ( int i = 0; i < dl; ++i ) {
            now <<= 1;
            if ( data[i] == 'o' ) now++, snum++;
        }
        //cout << now << endl;
        dfs( now, 0 );
        printf("%d\n", snum-ans);
    }
}



你可能感兴趣的:(UVa 10651 Pebble Solitaire (DFS))