luogu2346 四子连棋
题目大意
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。求用最少的步数移动到目标棋局的步数。
总体思路很简单,Bfs即可,只是需要注意以下几点:
- memcmp的返回值不一定是-1, 0, 1,而是<0, =0, >0的某个数。这在windows和linux上的效果不一样。
- 注意:黑白双方交替走棋。
- 任意一方都必须走一步。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <queue>
- #include <set>
- #include <cassert>
- using namespace std;
- const int MAX_N = 10;
- const int N = 4;
- const int Dir[4][2] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
- struct Node
- {
- char A[MAX_N][MAX_N];
- int Level;
- char NextColor;
- Node()
- {
- memset(A, 0, sizeof(A));
- Level = 0;
- }
- Node operator = (const Node& a)
- {
- memcpy(A, a.A, sizeof(A));
- Level = a.Level;
- NextColor = a.NextColor;
- return *this;
- }
- bool operator < (const Node& a) const
- {
- if (NextColor != a.NextColor)
- return NextColor == 'B';
- else
- return memcmp(A, a.A, sizeof(A)) < 0;
- }
- bool operator == (const Node& a) const
- {
- return NextColor == a.NextColor && memcmp(A, a.A, sizeof(A)) == 0;
- }
- void OPos1(int &oRow1, int &oCol1)
- {
- for (int row = 1; row <= N; row++)
- for (int col = 1; col <= N; col++)
- if (A[row][col] == 'O')
- {
- oRow1 = row;
- oCol1 = col;
- return;
- }
- }
- void OPos2(int &oRow2, int &oCol2)
- {
- int oRow1, oCol1;
- OPos1(oRow1, oCol1);
- for (int col = oCol1 + 1; col <= N; col++)
- if (A[oRow1][col] == 'O')
- {
- oRow2 = oRow1;
- oCol2 = col;
- return;
- }
- for (int row = oRow1 + 1; row <= N; row++)
- for (int col = 1; col <= N; col++)
- if (A[row][col] == 'O')
- {
- oRow2 = row;
- oCol2 = col;
- return;
- }
- assert(0);
- }
- bool CanMove1(const int dRow, const int dCol)
- {
- int oRow1, oCol1;
- OPos1(oRow1, oCol1);
- int nextRow = oRow1 + dRow, nextCol = oCol1 + dCol;
- return A[nextRow][nextCol] == NextColor && nextRow <= N && nextRow >= 1 && nextCol <= N && nextCol >= 1;
- }
- Node GetMove1(int dRow, int dCol)
- {
- int oRow1, oCol1;
- OPos1(oRow1, oCol1);
- Node ans = *this;
- swap(ans.A[oRow1][oCol1], ans.A[oRow1 + dRow][oCol1 + dCol]);
- return ans;
- }
- bool CanMove2(const int dRow, const int dCol)
- {
- int oRow2, oCol2;
- OPos2(oRow2, oCol2);
- int nextRow = oRow2 + dRow, nextCol = oCol2 + dCol;
- return A[nextRow][nextCol] == NextColor && nextRow <= N && nextRow >= 1 && nextCol <= N && nextCol >= 1;
- }
- Node GetMove2(int dRow, int dCol)
- {
- int oRow2, oCol2;
- OPos2(oRow2, oCol2);
- Node ans = *this;
- swap(ans.A[oRow2][oCol2], ans.A[oRow2 + dRow][oCol2 + dCol]);
- return ans;
- }
- bool Ok()
- {
- for (int row = 1; row <= N; row++)
- {
- char st = A[row][1];
- bool ok = true;
- for (int col = 2; col <= N; col++)
- if (A[row][col] != st)
- {
- ok = false;
- break;
- }
- if (ok)
- return true;
- }
- for (int col = 1; col <= N; col++)
- {
- char st = A[1][col];
- bool ok = true;
- for (int row = 2; row <= N; row++)
- if (A[row][col] != st)
- {
- ok = false;
- break;
- }
- if (ok)
- return true;
- }
- char st = A[1][1];
- bool ok = true;
- for (int i = 2; i <= N; i++)
- if (A[i][i] != st)
- {
- ok = false;
- break;
- }
- if (ok)
- return true;
- st = A[1][N];
- ok = true;
- for (int row = 2, col = N - 1; row <= N; row++, col--)
- if (A[row][col] != st)
- {
- ok = false;
- break;
- }
- return ok;
- }
- };
- Node Start;
- int Bfs()
- {
- static queue<Node> q;
- static set<Node> cache;
- Node s1 = Start, s2 = Start;
- s1.NextColor = 'B';
- s2.NextColor = 'W';
- q.push(s1);
- q.push(s2);
- cache.insert(s1);
- cache.insert(s2);
- while (!q.empty())
- {
- Node cur = q.front();
- q.pop();
- if (!(cur == s1 || cur == s2) && cur.Ok())
- return cur.Level;
- for (int i = 0; i < 4; i++)
- {
- if (cur.CanMove1(Dir[i][0], Dir[i][1]))
- {
- Node next = cur.GetMove1(Dir[i][0], Dir[i][1]);
- next.NextColor = (cur.NextColor == 'B' ? 'W' : 'B');
- if (!cache.count(next))
- {
- next.Level = cur.Level + 1;
- cache.insert(next);
- q.push(next);
- }
- }
- if (cur.CanMove2(Dir[i][0], Dir[i][1]))
- {
- Node next = cur.GetMove2(Dir[i][0], Dir[i][1]);
- next.NextColor = (cur.NextColor == 'B' ? 'W' : 'B');
- if (!cache.count(next))
- {
- next.Level = cur.Level + 1;
- cache.insert(next);
- q.push(next);
- }
- }
- }
- }
- return -1;
- }
- int main()
- {
- for (int i = 1; i <= 4; i++)
- scanf("%s", Start.A[i] + 1);
- printf("%d\n", Bfs());
- return 0;
- }
luogu2346 四子连棋的更多相关文章
- codevs1004四子连棋[BFS 哈希]
1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗 ...
- Codevs p1004 四子连棋
四子连棋 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向 ...
- 【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋
一.写在前面 其实这是一道大水题,而且还出在了数据最水的OJ上,所以实际上这题并没有什么难度.博主写这篇blog主要是想写下一个想法--状态压缩.状态压缩在记录.修改状态以及判重去重等方面有着极高的( ...
- codevs 1004 四子连棋
1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白 ...
- codevs 1004 四子连棋 BFS、hash判重
004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋 ...
- 【洛谷 P2346】四子连棋(状态压缩,搜索)
其实这题可以直接二进制状压做,1表示黑棋,0表示白棋,另外记录下2个空点的位置就行了. 具体看代码(冗长): #include <iostream> #include <cstdio ...
- 迭代加深搜索[codevs1004 四子连棋]
迭代加深搜索 一.算法简介 迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式.由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案. 迭代加深搜索适用于当 ...
- codevs1004四子连棋
1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白 ...
- P2346 四子连棋
P2346 四子连棋 迭代加深++ 题意描述 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋 ...
随机推荐
- 十年后我不会log,还是活的很好啊
混迹于互联网也一两年了,出于喜爱与生活压力依然会从事很久.迟迟不写博客,大概是觉得知识与经验积累在笔记上时不时看看就好了,而实际情况是笔记很少翻,遇到问题搜博客和百度依然是首选,故开通博客记录自己工作 ...
- java基础学习之内存分析(栈、堆、方法区)
栈存放:会为每个方法(包括构造函数)开辟一个栈指针,方法执行完毕后,会自动退出,并释放空间,主要每个方法中的存放局部变量 局部变量 先进后出 自下而上存储 方法执行完毕 自动释放空间 堆: 存放n ...
- IDEA中springboot项目打包成jar
springboot的打包方式有很多种.有打成war的,有打成jar的,也有直接提交到github,通过jekins进行打包部署的.这里主要介绍如何打成jar进行部署.不推荐用war,因为spri ...
- Could not resolve type alias 'map '. Cause: java.lang.ClassNotFoundException: Cannot find class: map
把resultType改为resultMap, 把parameterType改为parameterMap,重新发布并运行.
- Don't make me think [读书笔记] [思维导图]
<Don't make me think>第3版 内容:解析用户心理,在用户模式.扫描设计.导航设计.主页布局.可用性测试,提出了许多的独到观点及建议. 特色:语言轻松.实在.配有许多 ...
- 微信小程序,获取点击元素的索引值index
1.需求说明 点击 “加号图片” 上传图片,需要知道点击的是第几个图片,动态的修改src数组,这里图片用的 wx:for 循环出来的 2.遇到问题 按照官方最新文档循环的方式,索引值是以 wx:fo ...
- CCF201609-2 火车购票 java(100分)
试题编号: 201609-2 试题名称: 火车购票 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一 ...
- fillder抓取APP数据之小程序
1.下载fillder ,fillder官网:https://www.telerik.com/fiddler 2.安装好后设置fillder: 工具—>选项,打开设置面板.选择HTTPS选项卡. ...
- 部署live555到云
1.下载live555源码: wget http://www.live555.com/liveMedia/public/live.2017.10.28.tar.gz 2.解压源码包: ...
- Quadtrees(四分树)
uva 297 Quadtrees Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Subm ...