CCF 消除类游戏

/**
*@author StormMaybin
*@Date 2016-09-09
*/

生命不息,奋斗不止!

题目描述

这里写图片描述

样例输入输出

这里写图片描述

样例说明

这里写图片描述

题目分析

简直水题,直接暴力模拟之即可,但是唯一要注意的是一个棋子可能在某一行和某一列同时被消去,那么如果直接在原map上面修改的话会导致小错误,具体是什么错误呢 我们来看个例子:
2 2 2
2 3 3
2 1 1
假如map数组是这个样子,那么我们要开始先消除行,变成
0 0 0
2 3 3
2 1 1
然后,看看这个map数组,好像没什么要消除的了,然后输出,恭喜入坑,答案错误,不过ccf是oi赛制,还是会得一点点辛苦分的,那么看看一个巧妙的处理方式吧!
其实我们可以定义一个和map一样大小的数组来投影map数组中相同的行列,比如
2 2 2
2 3 3
2 1 1
我们定义一个数组arr初始化
1 1 1
1 1 1
1 1 1
然后我们来投影map满足条件的行列(如果相同在arr数组改成0)那么投影完arr数组变为
0 0 0
0 1 1
0 1 1
然后根据arr数组来修改map得到正确答案,哈哈哈哈


AC代码
import java.util.Arrays;
import java.util.Scanner;

/***
 * 思路 我们可以把相同的行和列投影到另外一个数组中去 !
 * @author StormMaybin
 */
public class Test2
{
    private Scanner scan;

    public Test2()
    {
        scan = new Scanner(System.in);
        while (scan.hasNext())
        {
            int n = scan.nextInt();
            int m = scan.nextInt();
            int[][] map = new int[31][31];
            int[][] flags = new int[31][31];
            //初始化投影
            for (int i = 0; i < 31; i++)
                Arrays.fill(flags[i], 1);
            //录入
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    map[i][j] = scan.nextInt();
            int flag = 1;
            // 消除行
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    if (j < m - 1 && map[i][j] == map[i][j + 1])// 边界
                        flag++;
                    else
                    {
                        // 开始投影标记
                        if (flag >= 3)
                        {
                            while (flag != 0)
                            {
                                flags[i][j+1-flag] = 0;
                                flag--;
                            }
                        }
                        flag = 1;
                    }
                }
            }
            // 消除列
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (j < n - 1 && map[j][i] == map[j + 1][i])// 边界
                        flag++;
                    else
                    {
                        if (flag >= 3)
                        {
                            while (flag != 0)
                            {
                                flags[j+1-flag][i] = 0;
                                flag--;
                            }
                        }
                        flag = 1;
                    }
                }
            }
            // 结果
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    if (flags[i][j] == 0)
                        map[i][j] = 0;
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    System.out.print(map[i][j] + " ");
                }
                System.out.println();
            }
        }
    }
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        new Test2();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值