日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

棋盘游戏(信息学奥赛一本通-T1451)

發布時間:2025/3/17 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 棋盘游戏(信息学奥赛一本通-T1451) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目描述】

在一個 4×4 的棋盤上有 8 個黑棋和 8 個白棋,當且僅當兩個格子有公共邊,這兩個格子上的棋是相鄰的。移動棋子的規則是交換相鄰兩個棋子。

給出一個初始棋盤和一個最終棋盤,請找出一個最短的移動序列使初始棋盤變為最終棋盤。

【輸入】

前四行,每行 4 個數字(1 或者 0 ),描述了初始棋盤;

接著是一個空行;

第六到第九行,每行 4 個數字(1 或者 0),描述了最終棋盤。

【輸出】

一行是一個整數 n,表示最少的移動步數。

【輸入樣例】

1111
0000
1110
0010

1010
0101
1010
0101

【輸出樣例】

4

思路:

本題是要從一個大狀態變到另一個大狀態,并且求其最小步數,很容易看出應用 BFS 來做

可以看出,每個單元非 0 即 1,共有 16 個單元,這樣可以將每個棋盤當做一個 16 位的二進制數,將其轉為十進制后再存儲狀態,最多有 2^16=65535 種狀態

對于每種狀態,由高到低枚舉每個位置,計算該位置在棋盤上的坐標 (x,y),理論上來說,格子可與其上下左右相鄰的四個格子任意進行交換,但顯然,但采用異或運算交換兩個相鄰格子時,對每個格子四方向的枚舉互換會造成大量的重復,因此,只要對每個格子從上到下,從左到右去嘗試互換即可

【源程序】

#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<bitset> #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long #define Pair pair<int,int> LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; } LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;} LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;} LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; } LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); } LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); } LL LCM(LL x,LL y){ return x/GCD(x,y)*y; } const double EPS = 1E-6; const int MOD = 1000000000+7; const int N = 1000+5; const int dx[] = {0,0,-1,1,1,-1,1,1}; const int dy[] = {1,-1,0,0,-1,1,-1,1}; using namespace std;struct Node {int val;int step;Node() {}Node(int val, int step) : val(val), step(step) {} }; int vis[65536 + 10]; void BFS(Node st, Node ed) {memset(vis, 0, sizeof(vis));queue<Node> Q;Q.push(st);while (!Q.empty()) {Node now = Q.front();Q.pop();if (now.val == ed.val) {cout << now.step << endl;return;}int val = now.val;int step = now.step;for (int i = 15; i >= 0; i--) { //從高到低枚舉每一位int x = (15 - i) / 4, y = (15 - i) % 4; //橫縱坐標int nowPos = 1 << i; //當前位置代表權值int rightPos = 1 << (i - 1); //當前位置右方位置代表權值int downPos = 1 << (i - 4); //當前位置下方位置代表權值if (y < 3 && ((val & nowPos) != (val & rightPos))) { //向右交換int nextVal = val ^ nowPos ^ rightPos; //交換后的狀態if (!vis[nextVal]) {vis[nextVal] = true;Q.push(Node(nextVal, step + 1));}}if (x < 3 && ((val & nowPos) != (val & downPos))) { //向下交換int nextVal = val ^ nowPos ^ downPos; //交換后的狀態if (!vis[nextVal]) {vis[nextVal] = true;Q.push(Node(nextVal, step + 1));}}}} } int main() {char ch;int st = 0, ed = 0;for (int i = 15; i >= 0; i--) {cin >> ch;if (ch == '1')st += 1 << i;}for (int i = 15; i >= 0; i--) {cin >> ch;if (ch == '1')ed += 1 << i;}if (st == ed)printf("0\n");elseBFS(Node(st, 0), Node(ed, 0));return 0; }

?

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的棋盘游戏(信息学奥赛一本通-T1451)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。