116. 飛行員兄弟(Acwing)(遞迴+位運算)
阿新 • • 發佈:2020-05-05
116. 飛行員兄弟
題目連結:
https://www.acwing.com/problem/content/118/
題解:
1、遞迴:
遞迴的最難理解的點就是要從滿足題目的從左向右,從上到下,所以遇到y == 4的邊界時,就應該跳到下一行的第一個位置,注意恢復現場。
2、位運算:
和95、費解的開關差不多,但是這裡是窮舉2^16種可能,直接判斷,利用getValue(int x,int y)將物理一維轉化為二維的窮舉。
AC程式碼:
1、遞迴
public class NO116 { static char[][] arr = new char[4][4]; static LinkedList<Pair> res = new LinkedList<>(); static Pair[] pairRes = null; static int step = 1000; static void turn(int x,int y) { for (int i = 0; i < 4; i++) { arr[x][i] ^= 1; arr[i][y] ^= 1; } arr[x][y] ^= 1; } static void dfs(int x,int y ) { if (x == 3 && y == 4) { boolean flag = true; pos: for (int i = 0 ;i < 4;i++) { for (int j = 0;j<4;j++) { if (arr[i][j] == ‘0‘){ flag = false; break pos; } } } if (flag && res.size() < step) { step = res.size(); pairRes = res.toArray(new Pair[0]); } return; } if (y == 4) { // 從左向右,從上到下 x = x+1; y = 0; } // 操作門把手 turn(x,y); res.push(new Pair(x+1,y+1)); dfs(x,y+1); // 恢復現場 turn(x,y); res.pop(); // 不操作門把手 dfs(x,y+1); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); for (int i = 0; i < 4; i++) { arr[i] = sc.next().toCharArray(); } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) arr[i][j] = arr[i][j] == ‘-‘ ? ‘1‘ : ‘0‘; } dfs(0,0); System.out.println(step); for (int i = pairRes.length-1; i >= 0; i--) { System.out.println(pairRes[i].x + " " + pairRes[i].y); } } } class Pair { int x,y; public Pair() {} public Pair(int x,int y) { this.x = x; this.y = y; } }
2、位運算
public class NO116 { static char[][] arr = new char[4][4]; static char[][] temp = new char[4][4]; static List<Pair> res = new ArrayList<>(); static Pair[] pairRes = null; static int step = 1000; static int getValue(int x,int y) { return x*4 + y; } static void turn(int x,int y) { for (int i = 0; i < 4; i++) { arr[x][i] ^= 1; arr[i][y] ^= 1; } arr[x][y] ^= 1; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); for (int i = 0; i < 4; i++) { arr[i] = sc.next().toCharArray(); } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) arr[i][j] = arr[i][j] == ‘-‘ ? ‘1‘ : ‘0‘; } for (int op = 0;op < 1<<16;op++) { for (int i = 0;i <4;i++) temp[i] = Arrays.copyOf(arr[i],arr[i].length); res.clear(); for (int i = 0;i < 4;i++) { for (int j = 0;j < 4;j++) { if( (op >> getValue(i,j) & 1) == 1) { turn(i,j); res.add(new Pair(i+1,j+1)); } } } boolean flag = true; pos: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (arr[i][j] == ‘0‘) { flag = false; break pos; } } } if (flag && res.size() < step) { step = res.size(); pairRes = res.toArray(new Pair[0]); } for (int i = 0;i <4;i++) arr[i] = Arrays.copyOf(temp[i],temp[i].length); } System.out.println(step); for (int i = 0; i < pairRes.length; i++) { System.out.println(pairRes[i].x + " " + pairRes[i].y); } } } class Pair { int x,int y) { this.x = x; this.y = y; } }