poj 1027 深搜

题意:在一个固定大小为10x15的矩形区域A内被RGB三种颜色的小球填满。

现在按如下步骤操作:

1、 删除区域A内最大的一片区域M(任意颜色都可以,只要其占有区域最大)

2、 删除M后,自然会出现空的位置,在M区域上方的小球自然下落;当删除M后出现空列时,右边的列往左填充。注意是以“列”为单位填充,非空列只能整列往空列移动。移动后,各个小球之间的相对顺序 与 移动前一样。

3、 当区域A剩余小球数为0,或A内的最大区域为1时,游戏结束。

 

 

char b[10][16],c[10][16];

int best_i,best_j,best_cnt;
int now_i, now_j, now_cnt;
int score;

void dfs(int i,int j){
    if(j<now_j) now_j=j; 
    if(j==now_j&&i>now_i) now_i=i; 
    now_cnt++;
    b[i][j]='1';
    if(i-1>=0&&c[i-1][j]==c[i][j]&&b[i-1][j]=='0') dfs(i-1,j); 
    if(i+1<10&&c[i+1][j]==c[i][j]&&b[i+1][j]=='0') dfs(i+1,j); 
    if(j-1>=0&&c[i][j-1]==c[i][j]&&b[i][j-1]=='0') dfs(i,j-1); 
    if(j+1<15&&c[i][j+1]==c[i][j]&&b[i][j+1]=='0') dfs(i,j+1); 
}

void mark(int i,int j) { //最大区域标记为2
    best_cnt++;
    b[i][j]='2';
    if(i-1>=0&&c[i-1][j]==c[i][j]&&b[i-1][j]!='2') mark(i-1,j); 
    if(i+1<10&&c[i+1][j]==c[i][j]&&b[i+1][j]!='2') mark(i+1,j); 
    if(j-1>=0&&c[i][j-1]==c[i][j]&&b[i][j-1]!='2') mark(i,j-1); 
    if(j+1<15&&c[i][j+1]==c[i][j]&&b[i][j+1]!='2') mark(i,j+1); 
}

void init(){                                                              //       cout<<"              init"<<endl;
    for(int i=0;i<10;i++)
        for(int j=0;j<15;j++)
            b[i][j]='0'; 
    best_i=best_j=16;
    best_cnt=0;
}

void prepare(){                                                                    //     cout<<"              prepare"<<endl;
    for(int j=0;j<15;j++)  //确定当前最大数量和相应的最左下角的坐标
        for(int i=9;i>=0;i--) 
            if(b[i][j]=='0'&&c[i][j]!='x') {
                now_cnt=0;
                now_i=i;
                now_j=j;
                dfs(i,j);       //深搜
                if(now_cnt>best_cnt) {
                    best_cnt=now_cnt;
                    best_i=now_i;
                    best_j=now_j;                                 //                cout<<best_i<<' '<<best_j<<' '<<best_cnt<<endl;
                }
                else if(now_cnt==best_cnt) {
                    if(now_j<best_j) {
                        best_i=now_i;
                        best_j=now_j;
                    }
                    else if(now_j==best_j&&now_i>best_i)  best_i=now_i; 
                }
            }
}

void move() {                                                                 //       cout<<"              move"<<endl;
    for(int j=0;j<15;j++) 
        for(int i=9;i>=0;i--) 
            if(b[i][j]=='2') {
                int m=i,n=j;
                int num=0;
                while(m>=0&&b[m][n]=='2') {
                    num++;
                    m--;
                }
                for(m=i;m-num>=0;m--) {
                    c[m][n]=c[m-num][n];
                    b[m][n]=b[m-num][n];
                }
                for(;m>=0;m--) {
                    c[m][n]='x';
                    b[m][n]='x';
                }
            }
            
    for(int j=0;j<15;j++) 
        if(c[9][j]=='x') {
            int n=j,num=0;
            while(n<15&&c[9][n]=='x') {
                num++;
                n++;
            }
            if(n==15) break; 
            for(int i=0;i<10;i++) {
                for(n=j;n+num<15;n++) {
                    c[i][n]=c[i][n+num];
                    b[i][n]=b[i][n+num];
                }
                for(;n<15;n++) {
                    c[i][n]='x';
                    b[i][n]='x';
                }
            }
        }
}

void readData() {
    for(int i=0;i<10;i++) cin>>c[i]; 
}

int main() {
    int t;
    cin>>t;
    for(int r=1;r<=t;r++) {
        readData();
        cout<<"Game "<<r<<":"<<endl<<endl;
        score=0;
        int cnt=0;
        int num=150;
        while(1) {
            init();
            prepare();
            if(best_cnt==1) break; 
            if(best_cnt==0) {
                score+=1000;
                break;
            }
            best_cnt=0;
            mark(best_i,best_j);
            cnt++;
            num-=best_cnt;
            int points=(best_cnt-2)*(best_cnt-2);
            score+=points;
            cout<<"Move "<<cnt<<" at ("<<10-best_i<<","<<best_j+1<<"): removed "<<best_cnt<<" balls of color "<<c[best_i][best_j]<<", got "<<points<<" points. "<<endl;
            move();
        }
        cout<<"Final score: "<<score<<", with "<<num<<" balls remaining."<<endl<<endl;
    }

    return 0;
}

 

posted @ 2013-06-20 19:59  心向往之  阅读(167)  评论(0编辑  收藏  举报