【模拟】POJ_1027_The Same Game

我马克思无话可说。。

有空列向左移动的时候出了点问题,死循环。。

#include <stdio.h>
#include <string.h>
//#include <queue>
#define INF 0x3f3f3f3f
//using namespace std;
int dx[]= {1,-1,0,0};
int dy[]= {0,0,1,-1};
char Map[15][25];
int vis[15][25],cnt=0,a[1010];
struct p
{
    int x,y;
} q[1000010];
int bfs(int x,int y)//找联通块
{
    int front=0,rear=0;
    cnt++;//记录当前联通块的序号
    int sum=0;//记录当前联通块内的格子数量
    //queue<p>q;
    struct p cur;
    cur.x=x;
    cur.y=y;
    sum++;
    //q.push(cur);
    q[rear++]=cur;
    vis[x][y]=cnt;
    //while(!q.empty())
    while(front<rear)
    {
        // struct p t=q.front();
        struct p t=q[front];
        for(int i=0; i<4; i++)
        {
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(!vis[tx][ty]&&tx>=0&&tx<10&&ty>=0&&ty<15&&Map[tx][ty]==Map[t.x][t.y])
            {
                vis[tx][ty]=cnt;
                cur.x=tx;
                cur.y=ty;
                sum++;
                q[rear++]=cur;
                // q.push(cur);
            }
        }
        //q.pop();
        front++;
    }
    //printf("%d\n",sum);
    a[cnt]=sum;
}
int Move(int x,int y)//
{
    for(int i=x; i<9; i++)
        Map[i][y]=Map[i+1][y];
    Map[9][y]='0';
}
int Move1(int y)
{
    for(int i=0; i<10; i++)
    {
        for(int j=y; j<14; j++)
            Map[i][j]=Map[i][j+1];
        Map[i][14]='0';
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cas=1; cas<=t; cas++)
    {
        int ans=0;
        for(int i=9; i>=0; i--)
            scanf("%s",Map[i]);
        printf("Game %d: \n\n",cas);
        //输出原图
//        printf("******************\n");
//        for(int i=9; i>=0; i--)
//        {
//            for(int j=0; j<15; j++)
//                printf("%c",Map[i][j]);
//            printf("\n");
//        }
        int c=0;
        while(1)
        {
            cnt=0;
            memset(vis,0,sizeof(vis));
            memset(a,0,sizeof(a));
            for(int i=9; i>=0; i--)
            {
                for(int j=0; j<15; j++)
                {
                    if(!vis[i][j]&&Map[i][j]!='0')
                        bfs(i,j);
                }
            }
//        输出bfs后的结果
//        printf("******************\n");
//        for(int i=9; i>=0; i--)
//        {
//            for(int j=0; j<15; j++)
//            {
//                printf("%d ",vis[i][j]);
//            }
//            printf("\n");
//        }
            //输出各联通块内格子的数量
//            printf("****************\n");
//            for(int i=1; i<=cnt; i++)
//                printf("%d ",a[i]);
//            printf("\n");
            int Max=1;//找到包含格子最多的联通块的序号
            for(int i=0; i<10; i++)
            {
                for(int j=0; j<15; j++)
                {
                    if(vis[i][j]&&a[Max]<a[vis[i][j]])
                    {
                        Max=vis[i][j];
                    }
                }
            }

            if(a[Max]==1||cnt==0)
            {
                if(cnt==0)
                    printf("Final score: %d, with 0 balls remaining.\n\n",ans+1000);
                else
                    printf("Final score: %d, with %d balls remaining.\n\n",ans,cnt);
                break;
            }
            ans+=(a[Max]-2)*(a[Max]-2);
            int mi=INF,mj=INF,f=1;
            for(int j=0; j<15; j++)//找最左下的
            {
                for(int i=0; i<10; i++)
                {
                    //printf("Max = %d\n vis[%d][%d] = %d\n",a[Max],i,j,vis[i][j]);
                    if(a[vis[i][j]]==a[Max])
                    {
                        //printf("(%d,%d)\n",i,j);
                        if(j<mj)
                        {
                            mi=i;
                            mj=j;
                        }
                        else if(j==mj&&i<mi)
                        {
                            mi=i;
                            mj=j;
                        }
                    }
                }
            }
            c++;
            printf("Move %d at (%d,%d): removed %d balls of color %c, got %d points.\n",c,mi+1,mj+1,a[Max],Map[mi][mj],(a[Max]-2)*(a[Max]-2));
            for(int i=9; i>=0; i--)
            {
                for(int j=0; j<15; j++)
                {
                    if(vis[i][j]==vis[mi][mj])
                        Move(i,j);
                }
            }
//            printf("******************\n");
//            for(int i=9; i>=0; i--)
//            {
//                for(int j=0; j<15; j++)
//                    printf("%c",Map[i][j]);
//                printf("\n");
//            }
            int cn=0;
            for(int j=0; j<15; j++)
            {
                int flag=1;
                for(int i=0; i<10; i++)
                {
                    if(Map[i][j]!='0')
                    {
                        flag=0;
                        break;
                    }
                }
                if(flag)
                {
                    cn++;
                }
            }
            while(cn--)
            {
                for(int j=0; j<15; j++)
                {
                    int flag=1;
                    for(int i=0; i<10; i++)
                    {
                        if(Map[i][j]!='0')
                        {
                            flag=0;
                            break;
                        }
                    }
                    if(flag)
                    {
                        Move1(j);
                        break;
                    }
                }
            }

//            printf("******************\n");
//            for(int i=9; i>=0; i--)
//            {
//                for(int j=0; j<15; j++)
//                    printf("%c",Map[i][j]);
//                printf("\n");
//            }
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值