poj 1027 The Same Game(大模拟)

题目链接:http://poj.org/problem?id=1027

大模拟题,没什么方法,就是写写写.......

code:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn=25;

int P[30][30];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m,sum,cc;
bool ff[30][30];

int dfs(int x,int y)
{
    ff[x][y]=true;
    int cnt=1;
    for(int i=0;i<4;i++){
        int mx=x+dir[i][0],my=y+dir[i][1];
        if(mx<0||mx>=n||my<0||my>=m) continue;
        if(ff[mx][my]) continue;
        if(P[mx][my]==P[x][y])  cnt+=dfs(mx,my);
    }
    return cnt;
}

void debug()
{
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++) printf("%d",P[i][j]);
        cout<<endl;
    }
}

int left_move(int x)
{
    int cnt=0;
    for(int j=x;j<m;j++){
        for(int i=0;i<n;i++){
            if(P[i][j]!=0) cnt++;
            P[i][j-1]=P[i][j];
            P[i][j]=0;
        }
    }
    return cnt;
}

void adjust()
{
    for(int i=n-2;i>=0;i--){
        for(int j=0;j<m;j++){
            for(int k=i+1;k<n;k++){
                if(!P[k][j]){
                    P[k][j]=P[k-1][j];
                    P[k-1][j]=0;
                }
            }
        }
    }
    for(int j=0;j<m;j++){
        int cnt=0;
        for(int i=0;i<n;i++) if(!P[i][j]) cnt++;
        if(cnt==n){
            if(left_move(j+1)!=0) j--;
        }
    }
}

bool work()
{
    int sx,sy,num,mid;
    char tt[3];
    sx=sy=num=0;
    cc++;
    memset(ff,false,sizeof(ff));
    for(int j=0;j<m;j++){
        for(int i=n-1;i>=0;i--){
            if(ff[i][j]||(!P[i][j])) continue;
            mid=dfs(i,j);
            if(mid>num){
                sx=i; sy=j;
                num=mid;
            }
        }
    }
    if(num<=1) return false;
    if(P[sx][sy]==1) tt[0]='R';
    else if(P[sx][sy]==2) tt[0]='G';
    else tt[0]='B';
    memset(ff,0,sizeof(ff));
    dfs(sx,sy);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(ff[i][j]) P[i][j]=0;
        }
    }
    //debug();
    adjust();
    sum+=(num-2)*(num-2);
    printf("Move %d at (%d,%d): removed %d balls of color %c, got %d points.\n",cc,n-sx,sy+1,num,tt[0],(num-2)*(num-2));
    return true;
}

int main()
{
    //freopen("output.txt","w",stdout);
    n=10; m=15;
    char c[maxn];
    int T,cnt;
    scanf("%d",&T);
    for(int kk=1;kk<=T;kk++){
        cc=0;
        sum=0;
        memset(P,0,sizeof(P));
        for(int i=0;i<n;i++){
            scanf("%s",c);
            for(int j=0;j<m;j++){
                if(c[j]=='R') P[i][j]=1;
                else if(c[j]=='G') P[i][j]=2;
                else P[i][j]=3;
            }
        }
        printf("Game %d:\n\n",kk);
        while(1){
            if(!work()) break;
        }
        cnt=0;
        for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(P[i][j]) cnt++;
        if(!cnt) sum+=1000;
        printf("Final score: %d, with %d balls remaining.\n",sum,cnt);
        if(kk!=T) printf("\n");
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值