【洛谷】P2730 魔板 Magic Squares
这道题显然是个宽搜(类似于8数码问题)。
只要每次按A、B、C三种方式进行宽度优先搜索,所以找到的第一次找到的解必定是步数最少的解。
另外,注意判重,(向用康托展开的dalao们膜拜),相比于康托展开(我这种菜蒟蒻听都没听过),我直接用c++的map<string,bool>来判重。
既不超空间,操作也很短~~(前提是,这里有大量字符串操作)
OK~下面附上AK代码:
#include<bits/stdc++.h> using namespace std; int front,rear,dep[5000005]; string how[5000005],zt[5000005],purpose; map <string,bool> mp; int main() { char ch; for (int i = 1 ; i <= 4 ; i ++) cin>>ch , purpose += ch; string tmp = ""; for (int i = 1 ; i <= 4 ; i ++) cin>>ch , tmp = ch + tmp; purpose += tmp; zt[1] = "12348765"; dep[1] = 0; how[1] = ""; mp[zt[1]] = 1; front = 1 ; rear = 1; while (front <= rear) { if (zt[front] == purpose) { cout<<dep[front]<<endl; int cnt = 0; for (int i = 0 ; i < how[front].length() ; i ++) { cnt ++; if (cnt == 60) cout<<how[front][i]<<endl , cnt = 0; else cout<<how[front][i]; } return 0; } //1: string st = zt[front].substr(4,8) + zt[front].substr(0,4); if (!mp[st]) { mp[st] = 1; rear ++; zt[rear] = st; dep[rear] = dep[front] + 1; how[rear] = how[front] + 'A'; } //2: st = zt[front][3]; st = st + zt[front].substr(0,3); st = st + zt[front][7] + zt[front][4] + zt[front][5] + zt[front][6]; if (!mp[st]) { mp[st] = 1; rear ++; zt[rear] = st; dep[rear] = dep[front] + 1; how[rear] = how[front] + 'B'; } //3: st = zt[front]; st[1] = zt[front][5]; st[2] = zt[front][1]; st[6] = zt[front][2]; st[5] = zt[front][6]; if (!mp[st]) { mp[st] = 1; rear ++; zt[rear] = st; dep[rear] = dep[front] + 1; how[rear] = how[front] + 'C'; } front ++; } return 0; }