acwing 116. 飛行員兄弟

地址  https://www.acwing.com/problem/content/118/ios

「飛行員兄弟」這個遊戲,須要玩家順利的打開一個擁有16個把手的冰箱。ide

已知每一個把手能夠處於如下兩種狀態之一:打開或關閉。spa

只有當全部把手都打開時,冰箱纔會打開。code

把手能夠表示爲一個4х4的矩陣,您能夠改變任何一個位置[i,j]上把手的狀態。xml

可是,這也會使得第i行和第j列上的全部把手的狀態也隨着改變。blog

請你求出打開冰箱所需的切換把手的次數最小值是多少。遊戲

輸入格式

輸入一共包含四行,每行包含四個把手的初始狀態。ci

符號「+」表示把手處於閉合狀態,而符號「-」表示把手處於打開狀態。get

至少一個手柄的初始狀態是關閉的。string

輸出格式

第一行輸出一個整數N,表示所需的最小切換把手次數。

接下來N行描述切換順序,每行輸入兩個整數,表明被切換狀態的把手的行號和列號,數字之間用空格隔開。

數據範圍

1i,j4

輸入樣例:
-+--
----
----
-+--
輸出樣例:
6
1 1
1 3
1 4
4 1
4 3
4 4
注意:若是存在多種打開冰箱的方式,則按照優先級總體從上到下,同行從左到右打開。

  

題解 沒有剪枝等捷徑 就是考覈位運算

使用int change[4][4] 記錄任意一個按鈕點擊後的變化

0~1<<16 二進制表明各類按鈕的按法組合 而後遍歷嘗試

代碼以下

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 
 5 
 6 using namespace std;
 7 
 8 typedef pair<int,int> PII;
 9 
10 
11 int change[4][4]={0};
12 
13 int get(int x,int y){
14     return x*4+y;
15 }
16 
17 
18 
19 int main()
20 {
21     int state = 0; 
22     for(int i = 0;i < 4;i++){
23         string tmpStr;
24         cin >> tmpStr;
25         for(int j = 0; j < tmpStr.size();j++){
26             if(tmpStr[j] == '+'){
27                 state += 1<<get(i,j);
28             }
29         }
30     }
31     
32     //製做每次點擊某個開關後的變化表格
33     for(int i =0;i < 4;i++){
34         for(int j = 0; j < 4;j++){
35             for(int k = 0; k < 4;k++){
36                 change[i][j] += 1<< get(i,k);
37                 change[i][j] += 1 <<get(k,j);
38             }
39             //選擇的點回增長兩次,減小1
40             change[i][j] -= 1 << get(i,j);
41         }
42     }
43     
44     vector<PII> res;
45     //遍歷各類可能的點擊開關的方案 16個按鈕選出任意N個點擊  從0-16個的排列組合就是0~ 1<<16;
46     for(int k = 0;k < 1 << 16;k++){
47         int now = state; 
48         vector<PII> path;
49         //當前選擇的點擊方案 點擊了那些按鈕
50         for(int i = 0; i< 16;i++){
51             if(k >> i & 1){
52                 //該按鈕按下了
53                  int x = i/4,y = i%4;
54                 now ^= change[x][y];
55                 path.push_back({x,y});
56             }
57             if(!now && ( res.empty() ||  res.size() > path.size() ))
58                 res = path;
59         }
60     }
61     
62      cout << res.size() << endl;
63     for(auto p : res)
64         cout << p.first +1 << ' ' << p.second+1 << endl;
65 
66     
67     return 0;
68 }
View Code
相關文章
相關標籤/搜索