题意:(1)有两副颜色多样的扑克牌,(A~H)表示不同颜色,给你两副牌,S1,S2和一副你需要洗出的KEY,S12由S2最底部,S1底部。。。一直下去,直到洗成S12,就是图片展示的那样。
(2)洗好的S12可以重新变成新的S1,S2,S1是从下取S12牌数的一半,S2的从上取S12牌数的一半,
问:这样操作有限次,能不能洗出S3,可以的话,求出最少洗牌次数,不能的话输出-1.
思路:算一个水题吧,简单的模拟,就是按照洗牌,拆牌那样模拟就好了,为了确定这个KEY能不能洗出,
需要一个map<string,bool>,标记每次洗出的牌S12的字符串,如果洗出了之前洗出过的牌S12,说明KEY无法被洗出。
1 #include <iostream>
2 #include <cstring>
3 #include<string>
4 #include <cmath>
5 #include <map>
6 #include <queue>
7 #include <algorithm>
8 using namespace std;
9
10 #define inf (1LL << 31) - 1
11 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
12 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
13 #define per(i,j,k) for(int i = (j); i >= (k); i--)
14 #define per__(i,j,k) for(int i = (j); i > (k); i--)
15
16 int ans;
17 string a, b, key;
18 int len;
19
20 //洗牌函数
21 inline void Insert(string& tmp, string& a, string& b){
22
23 int l = 0;
24 rep__(i, 0, len){
25 tmp[l++] = b[i];
26 tmp[l++] = a[i];
27 }
28 }
29
30 bool bfs(){
31
32 map<string, bool> mp;
33 string tmp(2*len,'0');
34 ans = 0;//初始化洗牌次数
35
36 Insert(tmp, a, b);
37
38 while (!mp[tmp]){ //该S12没出现过
39 mp[tmp] = true; //标记新S12
40 ++ans;
41 if (tmp == key) return true; //洗出了KEY
42
43 //把S12拆成S1和S2
44 rep__(i, 0, len) a[i] = tmp[i];
45 rep__(i, len, 2 * len) b[i - len] = tmp[i];
46
47 //重新洗牌
48 Insert(tmp, a, b);
49 }
50
51 //洗不出KEY
52 return false;
53 }
54
55 int main(){
56
57 ios::sync_with_stdio(false);
58 cin.tie(0);
59
60 int n;
61 cin >> n;
62
63
64 rep(i, 1, n){
65 cin >> len >> a >> b >> key;
66
67 cout << i << " ";
68 if (bfs()) cout << ans << endl;
69 else cout << "-1" << endl;
70 }
71
72 return 0;
73 }