ZOJ 3055 WW’s game (模拟题)

ZOJ 3055 WW’s game

昨天下午新人比赛,我想找个模拟题,然后从大黄的题解上随便找了一个,比赛中途,我想敲敲试试,没想到光看题就用了20分钟,敲题用了半个多小时,最后到吃饭时候也没把样例给过了,心情十分郁闷。晚上回去,突然发现那些候选数字是以0为结尾的,于是我就换个结束的方法while( scanf(“%d”,&n) && n );然后他就华丽丽地在我的眼前AC了。

模拟对对碰,不过规则改了改,他不是交换两个相邻的格子,而是移动一行或一列,如果存在三个颜色相同的在一行或者一列,消去。说实话,难度不大。需要注意的两点:1.把k个操作保存起来再进行模拟,2. 候选格子是以0结尾的,不一样都放在一行输入上。我的代码用类把各种操作封装了。。

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 11;
const int dir[4][2] = {1,0,0,1,0,-1,-1,0};
class MAP{
public:
    int N,M,K;
    int m[ maxn ][ maxn ];
    int flag[maxn][maxn];
    int used[maxn][maxn];
    int fuck[maxn][maxn];
    void leftshift( int row ){
        int i;
        for( i = 1; i <= M; i++ )
            m[row][i-1] = m[row][i];
        m[row][M] = m[row][0];
    }
    void upmove( int col ){
        int i;
        for( i = 1; i <= N; i++ )
            m[i-1][col] = m[i][col];
        m[N][col] = m[0][col];
    }
public:
    void getsize(void){scanf("%d%d",&N,&M);}
    void getins(void) {scanf("%d",&K);}
    void init(void){memset(flag,0,sizeof(flag)) ;}
    void getgrids(void){
        int i,j;
        for( i = 1; i <= N; i++ )
            for( j = 1; j <= M; j++ )
                scanf("%d",&m[i][j]);
    }
    void oprow( int i, int d ){
        while( d-- ) leftshift( i );
    } 
    void opcol( int i, int d ){
        while( d--  ) upmove( i );
    }
    
    void deleteg( int x,int y ){
        int i;char c;
        flag[x][y] = 1;
        for( i = x; i >= 1; i-- )
            m[i][y] = m[i-1][y];
        scanf("%d",&m[1][y]);
    }
    
    int destroy(void){
        memset( used, 0, sizeof(used) );
        memset( fuck, 0, sizeof(fuck) );
        int i,j,cnt = 1;
    
        for( i = 2; i < N; i++ )
            for( j = 1; j <= M; j++ )
                if( m[i-1][j] == m[i][j] && 
                    m[i+1][j] == m[i][j] ) 
                    fuck[i+1][j]=fuck[i-1][j]=fuck[i][j]=1;
        for( i = 1; i <= N; i++ )
            for( j = 2; j < M; j++ )
                if( m[i][j+1] == m[i][j] && 
                    m[i][j-1] == m[i][j] ) 
                    fuck[i][j-1]=fuck[i][j+1]=fuck[i][j]=1;
            
       // pri();
        cnt = 0;   
        for( j = 1; j <= M; j++ )
            for( i = 1; i <= N; i++ )
                if( fuck[i][j] ) cnt++,deleteg(i,j);
        return cnt;
    }
    
    int countMarked( void ){
        int i,j,cnt = 0;
        for( i = 1; i <= N; i++ )
            for( j = 1; j <= M; j++ )
                if( flag[i][j] ) cnt++;
        return cnt;
    }
    void pri( void ){
        int i,j;
        for( i = 1; i <= N; i++ ){
            for( j = 1; j <= M; j++ )
                printf("%d ",m[i][j]);
            puts("");
        }
    }
};



MAP Map;
int ins[ 1000 ][3];
int main(void){
    int T,i,j,k,N,M,K;
    int a,b,c;char s[1000];
    scanf("%d",&T);
    while( T-- ){
        Map.init();
        Map.getsize();
        Map.getgrids();
        scanf("%d",&K);
        for( i = 0; i < K; i++ )
            scanf("%d%d%d",&ins[i][0],&ins[i][1],&ins[i][2]);
        for( i = 0; i < K; i++ ){
            a = ins[i][0];
            b = ins[i][1];
            c = ins[i][2];
            if( a == 1 ) Map.oprow(b,c);
            if( a == 2 ) Map.opcol(b,c);
            while( 1 ){
                if( !Map.destroy() )
                    break;
            }
        }
        while( scanf("%d",&i) && i );//因为这里错了几次 = =
        printf("%d\n", Map.countMarked() );
    }
    return 0;
}

关于 “ZOJ 3055 WW’s game (模拟题)” 的 5 个意见

      1. 模拟一般都都一步一步按照题目的要求来,他让移动的以后移动,需要消去的时候消去。。。然后。。模拟的时候也不用太考虑时间复杂度,一般不卡这个的

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注