Pebble Solitaire(UVA 10651)

Pebble solitaire is an interesting game. This is a game where you are given a board with an arrangement of small cavities, initially all but one occupied by a pebble each. The aim of the game is to remove as many pebbles as possible from the board. Pebbles disappear from the board as a result of a move. A move is possible if there is a straight line of three adjacent cavities, let us call them AB, and C, with B in the middle, whereA is vacant, but B and C each contain a pebble. The move constitutes of moving the pebble from C to A, and removing the pebble in B from the board. You may continue to make moves until no more moves are possible.

 

In this problem, we look at a simple variant of this game, namely a board with twelve cavities located along a line. In the beginning of each game, some of the cavities are occupied by pebbles. Your mission is to find a sequence of moves such that as few pebbles as possible are left on the board.

 

Input

The input begins with a positive integer n on a line of its own. Thereafter n different games follow. Each game consists of one line of input with exactly twelve characters, describing the twelve cavities of the board in order. Each character is either '-' or 'o' (The fifteenth character of English alphabet in lowercase). A '-' (minus) character denotes an empty cavity, whereas a 'o' character denotes a cavity with a pebble in it. As you will find in the sample that there may be inputs where no moves is possible.

 

Output

For each of the n games in the input, output the minimum number of pebbles left on the board possible to obtain as a result of moves, on a row of its own.

 

Sample Input                              Output for Sample Input

5

---oo-------

-o--o-oo----

-o----ooo---

oooooooooooo

oooooooooo-o

1

2

3

12

1

  



题解:dfs,由于有12个位置,需要2^12个数来记录中间值

代码:c++ 

//Memory:0Kb ; Time:12ms

code1:使用数组记录中间结果

#include<stdio.h>
#define min(x,y) (x<y?x:y)
char buf[13];
int F[4100];
int dfs(int s){
    if(F[s]<13) return F[s];  //avoid the repeat calculator
    int Min=12;
    for(int a=0;a<10;a++){
        if(((s>>a)&7)==6||((s>>a)&7)==3){
            Min=min(Min,dfs(s^(7<<a)));
        }
    }
    if(Min==12){
        for(int i=0;i<12;i++){
            Min-=!(s&(1<<i));
        }
    }
    return F[s]=Min;
}
int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        scanf("%s",buf);
        int s;
        s=0;
        for(int a=0;a<12;a++){
            s<<=1;
            if(buf[a]=='o'){
                s+=1;
            }
        }
        for(int a=0;a<4100;a++){
            F[a]=13;
        }
        printf("%d\n",dfs(s));
    }
    return 0;
}

code2:

#include<stdio.h>
#define min(x,y) (x<y?x:y)
char buf[13];
int dfs(int s){
    int Min=12;
    for(int a=0;a<10;a++){
        if(((s>>a)&7)==6||((s>>a)&7)==3){
            Min=min(Min,dfs(s^(7<<a)));
        }
    }
    if(Min==12){
        for(int i=0;i<12;i++){
            Min-=!(s&(1<<i));
        }
    }
    return Min;
}
int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        scanf("%s",buf);
        int s;
        s=0;
        for(int a=0;a<12;a++){
            s<<=1;
            if(buf[a]=='o'){
                s+=1;
            }
        }
        printf("%d\n",dfs(s));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值