题目来源:小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 }