[SCOI2005]扫雷MINE

相信大家都玩过扫雷的游戏。那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来。 万圣节到了 ,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字 表示和它8连通的格子里面雷的数目。 现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷,如下图: 由于第一列的雷可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息确定第一列雷有多少种摆放方案。

输入描述:

第一行为N,第二行有N个数,依次为第二列的格子中的数。(1 ≤ N ≤ 10000)

输出描述:

一个数,即第一列中雷的摆放方案数。

分析

我们可以假设第一个的情况, 假设第一个不是雷, 将flags[1]置为0, 根据flags[i - 1]和flags[i]跟arr[i]的情况可以得到flags[i + 1]位置的情况, 因此可以自上而下证明。
如果flags[i - 1] + flags[i] 已经超过了arr[i], 假设不成立。
如果flags[i - 1] + flags[i] 恰好等于arr[i], 这块区域雷的数量已经足够, flags[i + 1]不是雷, 置为0。
如果flags[i - 1] + flags[i] 小于arr[i], flags[i + 1]一定是雷,置为1,但是如果雷的数量加上了1还是小于arr[i]或者我们来到了最后一行, 假设不成立。
接着证明第一个是雷的情况。答案始终是0、1或者2。

AC

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(bf.readLine());
        String[] strs = bf.readLine().split(" ");
        int[] arr = new int[N + 1];
        int[] flags = new int[N + 2];
        int ans = 0;
        for(int i = 1; i <= N; ++i) {
            arr[i] = Integer.parseInt(strs[i - 1]);
        }
        for(int i = 0; i < 2; ++i) {
            flags[1] = i;
            int j = 1;
            for(; j <= N; ++j) {
                int cnt = flags[j - 1] + flags[j];
                if(cnt > arr[j])
                    break;
                else if(cnt == arr[j])
                    flags[j + 1] = 0;
                else {
                    if(j == N || cnt + 1 < arr[j])
                        break;
                    flags[j + 1] = 1;
                }
            }
            if(j > N)
                ++ans;
        }
        System.out.println(ans);
	} 
}

链接:https://ac.nowcoder.com/acm/contest/20960/1032
来源:牛客网

posted @ 2022-02-11 00:10  brbrbr  阅读(41)  评论(0)    收藏  举报