hihoCoder 1114 小Hi小Ho的惊天大作战:扫雷·一 最详细的解题报告

题目来源:小Hi小Ho的惊天大作战:扫雷·一

解题思路:因为只要确定了第一个是否有地雷就可以推算出后面是否有地雷(要么为0,要么为1,如果不是这两个值就说明这个方案行不通),如果两种可能中有一种成功,只需要计算包含有多少个1和多少个0,如果两种可能都成功了,都为1的才是有雷,都为0的才是没有地雷。

具体算法(java版,可以直接AC)

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4 
  5     public static boolean flag1 = true;//当第一个为1(有雷)时,依次推算后的结果
  6     public static boolean flag2 = true;//当第一个为0(没雷)时,依次推算后的结果
  7 
  8     public static void solve(int[] maze, int[][] mine, int N) {
  9         mine[0][1] = 1;//第一个有雷
 10         mine[1][1] = 0;//第一个没雷
 11 
 12         for (int i = 2; i <= N; i++) {
 13             if (flag1) {
 14                 mine[0][i] = maze[i - 1] - mine[0][i - 1] - mine[0][i - 2];
 15                                 //要么有雷,要么没雷
 16                 if (mine[0][i] == 1 || mine[0][i] == 0) {
 17                     flag1 = true;
 18                 } else {
 19                     flag1 = false;//推算失败
 20                     break;
 21                 }
 22             }
 23         }
 24 
 25         for (int i = 2; i <= N; i++) {
 26             if (flag2) {
 27                 mine[1][i] = maze[i - 1] - mine[1][i - 1] - mine[1][i - 2];
 28                 if (mine[1][i] == 1 || mine[1][i] == 0) {
 29                     flag2 = true;
 30                 } else {
 31                     flag2 = false;
 32                     break;
 33                 }
 34             }
 35         }
 36         if (flag1) {//验证最后一个是否正确
 37             if (maze[N] != mine[0][N - 1] + mine[0][N]) {
 38                 flag1 = false;
 39             }
 40         }
 41         if (flag2) {
 42             if (maze[N] != mine[1][N - 1] + mine[1][N]) {
 43                 flag2 = false;
 44             }
 45         }
 46     }
 47 
 48     public static void main(String[] args) {
 49         Scanner scanner = new Scanner(System.in);
 50         int task = scanner.nextInt();
 51         while (task > 0) {
 52             task--;
 53             int N = scanner.nextInt();
 54             int[] maze = new int[N + 1];
 55             int[][] mine = new int[2][N + 1];
 56             for (int i = 1; i <= N; i++) {
 57                 maze[i] = scanner.nextInt();
 58             }
 59             flag1 = flag2 = true;
 60             solve(maze, mine, N);
 61             int hasMine = 0, noMine = 0;//统计有雷和没雷的数量
 62             int[] hasMineAns = new int[N];
 63             int[] noMineAns = new int[N];
 64             if (flag1 && flag2) {//两种可能都成功
 65                 for (int i = 1; i <= N; i++) {
 66                     if (mine[0][i] == 1 && mine[1][i] == 1) {//同时为1(有雷)
 67                         hasMineAns[hasMine++] = i;
 68                     } else if (mine[0][i] == 0 && mine[1][i] == 0) {//同时为0(没雷)
 69                         noMineAns[noMine++] = i;
 70                     }
 71                 }
 72             } else if (flag1 && !flag2) {//其中一种可能是成功的,另外一种失败
 73                 for(int i=1;i<=N;i++){
 74                     if(mine[0][i]==1){
 75                         hasMineAns[hasMine++] = i;
 76                     }else{
 77                         noMineAns[noMine++] = i;
 78                     }
 79                 }
 80             } else if (!flag1 && flag2) {
 81                 for(int i=1;i<=N;i++){
 82                     if(mine[1][i]==1){
 83                         hasMineAns[hasMine++] = i;
 84                     }else{
 85                         noMineAns[noMine++] = i;
 86                     }
 87                 }
 88             }
 89             System.out.print(String.format("%d", hasMine));
 90             for(int i=0;i<hasMine;i++){
 91                 System.out.print(String.format(" %d", hasMineAns[i]));
 92             }
 93             System.out.print(String.format("\n%d", noMine));
 94             for(int i=0;i<noMine;i++){
 95                 System.out.print(String.format(" %d", noMineAns[i]));
 96             }
 97             System.out.println();
 98         }
 99         scanner.close();
100     }
101 }

 

posted @ 2016-03-06 21:10  PinXiong  阅读(591)  评论(0编辑  收藏  举报