[Codevs] 1004 四子连棋

1004 四子连棋

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
题目描述 Description

在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。

 
 

 

输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description

用最少的步数移动到目标棋局的步数。

 

样例输入 Sample Input

BWBO
WBWB
BWBW
WBWO

 

样例输出 Sample Output

5

 

分析 Analysis

搜索经典题

这道题只是看上去很难= =

首先我们要明确我们要做的事情:

输入 判断胜局 行棋 状态储存 状态判重 

其中行棋我们有:寻找行棋位 判断是否行棋 行棋

对于状态,我们有:棋盘 序列码(Hash码) 步数 行棋方

然后打一遍就过了= =

 

代码 Code

  1 #include<cstdio>
  2 #include<queue>
  3 #include<iostream>
  4 #include<cstring>
  5 #define LL long long
  6 using namespace std;
  7 
  8 const int dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
  9 int HASH[100000000];
 10 // State: Map Step Last HashCode?
 11 // Input:
 12 // Play: 
 13 //        FindSpace -> Move -> Hash? -> Check? -> Push
 14 //                                             -> Print
 15 // Check:
 16 //        X? -> Y? -> LU/RU?
 17 
 18 struct MAP{
 19     LL hashcode;
 20     int map[6][6],last,step;
 21     
 22     MAP(){
 23         memset(map,0,sizeof(map));
 24         last = step = hashcode = 0;
 25     }
 26 };
 27 
 28 queue<MAP> q;
 29 
 30 bool check(MAP now){
 31     for(int i = 1;i <= 4;i++)
 32     if(now.map[i][1] == now.map[i][2] && now.map[i][2] == now.map[i][3] && now.map[i][3] == now.map[i][4] ||
 33        now.map[1][i] == now.map[2][i] && now.map[2][i] == now.map[3][i] && now.map[3][i] == now.map[4][i]){
 34         return true;
 35     }
 36     
 37     if(now.map[1][1] == now.map[2][2] && now.map[2][2] == now.map[3][3] && now.map[3][3] == now.map[4][4] ||
 38        now.map[1][4] == now.map[2][3] && now.map[2][3] == now.map[3][2] && now.map[3][2] == now.map[4][1]){
 39         return true;       
 40     }
 41     
 42     return false;
 43 }
 44 
 45 bool GETCODE(MAP now){
 46     LL &code = now.hashcode;
 47     LL cnt = 1;
 48     for(int i = 1;i <= 4;i++){
 49         for(int j = 1;j <= 4;j++){
 50             code += now.map[i][j]*cnt;
 51             cnt *= 4;
 52         }
 53     }
 54     code += now.last*cnt;
 55     code %= 42137897;
 56     
 57     if(HASH[code]) return false;
 58     else{
 59         HASH[code] = 1;
 60         return true;
 61     }
 62 }
 63 
 64 void Input(){
 65     char ctmp;
 66     MAP sta;
 67     for(int i = 1;i <= 4;i++){
 68         for(int j = 1;j <= 4;j++){
 69             cin >> ctmp;
 70             switch(ctmp){
 71                 case 'B': sta.map[i][j] = 1; break;
 72                 case 'W': sta.map[i][j] = 2; break;
 73             }
 74         }
 75     }
 76     
 77     sta.step = 0;
 78     
 79     sta.last = 1;
 80     if(GETCODE(sta)) q.push(sta);
 81     sta.last = 2;
 82     if(GETCODE(sta)) q.push(sta);
 83 }
 84 
 85 void Move(MAP now,int x,int y){
 86     for(int i = 0;i < 4;i++){
 87         int nowx = x+dir[i][0];
 88         int nowy = y+dir[i][1];
 89         
 90         if(now.map[nowx][nowy] == now.last || !now.map[nowx][nowy]) continue;
 91         
 92         MAP cnt = now;
 93         
 94         cnt.map[x][y] = cnt.map[nowx][nowy];
 95         cnt.map[nowx][nowy] = 0;
 96         cnt.last = 3-now.last;
 97         cnt.step = now.step+1;
 98         
 99         if(GETCODE(cnt)) q.push(cnt);
100     }
101 }
102 
103 void Findspace(MAP now,int &x1,int &y1,int &x2,int &y2){
104     for(int i = 1;i <= 4;i++){
105         for(int j = 1;j <= 4;j++){
106             if(!now.map[i][j]){
107                 if(x1 == -1){
108                     x1 = i,y1 = j;
109                 }else{
110                     x2 = i,y2 = j;
111                 }
112             }
113         }
114     }
115 }
116 
117 void bfs(){
118     while(!q.empty()){
119         MAP tmp = q.front();
120         q.pop();
121         
122         if(check(tmp)){
123             if(!tmp.step) printf("1");
124             else printf("%d",tmp.step);
125             return;
126         }
127         
128         int x1 = -1,x2 = -1,y1 = -1,y2 = -1;
129         
130         Findspace(tmp,x1,y1,x2,y2);
131         
132         Move(tmp,x1,y1);
133         
134         Move(tmp,x2,y2);
135     }
136 }
137 
138 int main(){
139     
140     Input();
141     bfs();
142     
143     return 0;
144 }
= =心情很差

 

转载于:https://www.cnblogs.com/Chorolop/p/7325048.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

逻辑综合——优化电路

对进行时序路径、工作环境、设计规则等进行约束完成之后&#xff0c;DC就可以进行综合、优化时序了&#xff0c;DC在优化过程中主要的策略将在下面进行说明。然而&#xff0c;当普通模式下不能进行优化的&#xff0c;就需要我们进行编写脚本来改进DC的优化来达到时序要求。 DC…

DOM包裹wrap()方法

DOM包裹wrap()方法 如果要将元素用其他元素包裹起来&#xff0c;也就是给它增加一个父元素&#xff0c;针对这样的处理&#xff0c;JQuery提供了一个wrap方法 .wrap( wrappingElement )&#xff1a;在集合中匹配的每个元素周围包裹一个HTML结构 简单的看一段代码&#xff1a; &…

Verdi 基础教程

一、Verdi 功能 查看设计debugVerdi不能自己产生波形 二、Verdi使用流程 1、Verdi环境配置 .bashrc中配置 export Verdi_HOME$Synopsys_Dir/Verdi2015 #export NOVAS_HOME$Synopsys_Dir/Verdi2015 export PATH$Verdi_HOME/bin:$PATH export LD_LIBRARY_PATH"/opt/Syno…

ida和idr机制分析(盘符分配机制)

内核ida和idr机制分析&#xff08;盘符分配机制&#xff09; ida和idr的机制在我个人看来&#xff0c;是内核管理整数资源的一种方法。在内核中&#xff0c;许多地方都用到了该结构&#xff08;例如class的id&#xff0c;disk的id&#xff09;&#xff0c;更直观的说&#xff0…

MIPI CSI-2学习

CSI&#xff08;Camera Serial Interface&#xff09;定义了摄像头外设与主机控制器之间的接口&#xff0c;旨在确定摄像头与主机控制器在移动应用中的标准。 关键词描述 缩写解释CCICamera Control Interface&#xff08;物理层组件&#xff0c;通常使用I2C或I3C进行通信&…

nand flash坏块管理OOB,BBT,ECC

0.NAND的操作管理方式 NAND FLASH的管理方式&#xff1a;以三星FLASH为例&#xff0c;一片Nand flash为一个设备(device)&#xff0c;1 (Device) xxxx (Blocks)&#xff0c;1 (Block) xxxx (Pages)&#xff0c;1(Page) 528 (Bytes) 数据块大小(512Bytes) OOB 块大小(16Byte…

小白学git2

你已经在本地创建了一个Git仓库后&#xff0c;又想在GitHub创建一个Git仓库&#xff0c;并且让这两个仓库进行远程同步&#xff0c;这样&#xff0c;GitHub上的仓库既可以作为备份&#xff0c;又可以让其他人通过该仓库来协作&#xff0c;真是一举多得。 首先&#xff0c;登陆G…

CMOS图像传感器——工作原理

一、像素阵列结构 一般像素阵列是由水平方向的行( Row ) 和垂直方向的列(Column)正交排列构成的。像素排列的最基本设计原则是:摄像器件像素排列的坐标,必须在显示的时候能够准确地还原在图像原来的相对位置上。在大多数情况下,每个像素中心线在行的方向和列的方向,即…

追寻终极数据库 - 事务/分析混合处理系统的交付挑战 (3)

挑战&#xff1a;支持多个存储引擎 以下内容并不是新发现&#xff1a;行优化存储适用于OLTP和运营工作负载&#xff0c;而列存储适用于BI和分析工作负载。频繁写入的工作负载适用于行式存储。对Hadoop而言&#xff0c;Hbase适合低延迟工作负载&#xff0c;列式ORC文件或Parquet…

异步FIFO设计(Verilog)

FIFO&#xff08;First In First Out&#xff09;是异步数据传输时经常使用的存储器。该存储器的特点是数据先进先出&#xff08;后进后出&#xff09;。其实&#xff0c;多位宽数据的异步传输问题&#xff0c;无论是从快时钟到慢时钟域&#xff0c;还是从慢时钟到快时钟域&…

python中RabbitMQ的使用(路由键模糊匹配)

路由键模糊匹配 使用正则表达式进行匹配。其中“#”表示所有、全部的意思&#xff1b;“*”只匹配到一个词。 匹配规则&#xff1a; 路由键&#xff1a;routings [ happy.work, happy.life , happy.work.teacher, sad.work, sad.life, sad.work.teacher ] "#"&am…

时钟切换处理(Verilog)

随着各种应用场景的限制&#xff0c;芯片在运行时往往需要在不同的应用下切换不同的时钟源&#xff0c;例如低功耗和高性能模式就分别需要低频率和高频率的时钟。两个时钟源有可能是同源且同步的&#xff0c;也有可能是不相关的。直接使用选择逻辑进行时钟切换大概率会导致分频…

Angular Elements 组件在非angular 页面中使用的DEMO

2019独角兽企业重金招聘Python工程师标准>>> 一、Angular Elements 介绍 Angular Elements 是伴随Angular6.0一起推出的新技术。它借助Chrome浏览器的ShadowDom API&#xff0c;实现一种自定义组件。 这种组件可以用Angular普通组件的开发技术进行编写&#xff0c;…

卢卡斯定理

卢卡斯定理:解决一类组合数取模问题 A、B是非负整数&#xff0c;p是质数。AB写成p进制&#xff1a;Aa[n]a[n-1]...a[0]&#xff0c;Bb[n]b[n-1]...b[0]。 则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0]) modp同余 即&#xff1a;Lucas(n,m,p)c(n%p,m%p)*Luc…

loadrunner中对https证书的配置

1、准备好网站的证书&#xff0c;一般证书是cer格式&#xff1b; 2、因为loadrunner只支持pem格式的证书&#xff0c;所以要将证书转换格式&#xff0c;利用openssl工具&#xff1b;&#xff08;或者直接让开发提供pem格式的证书&#xff09;3、得到pem格式的证书之后&#xff…

Datapath综合代码规范(Verilog)

一、一般准则 1、有符号数运算 利用类型“signed”完成有符号数运算&#xff0c;而不是用无符号数模拟有符号数运算。这样可以得到更好的QoR。在资源报告中检查操作数的类型和大小。 2、符号/零扩展 尽量不要手动扩展。verilog利用signed/unsigned会自动完成扩展。这样代码可…

CMOS 图像传感器——Skipping 和 Binning 模式

在通常的CMOS读取方式中&#xff0c;由于像素读取规模的差异&#xff0c;不同的分辨率对应不同的帧率。在通道带宽固定的前提下&#xff0c;想要提高帧率就要考虑是否需要缩小视野&#xff08;外圈裁切&#xff09;。若不希望视野缩小&#xff0c;需要减少采样的分辨率。 常用的…

APB协议学习

APB(Advanced Peripheral Bus) 1、APB的概述与特点 APB主要用于低带宽的周边外设之间的连接&#xff0c;例如UART、1284等&#xff0c;它的总线架构不像AHB支持多个主模块&#xff0c;在APB里面唯一的主模块就是APB 桥。其特性包括&#xff1a;两个时钟周期传输&#xff1b;无…

私有协议栈开发

通信协议从广义上区分&#xff0c;可以分为公有协议和私有协议。由于私有协议的灵活性&#xff0c;它往往会在某个公司或者组织内部使用&#xff0c;按需定制&#xff0c;也因为如此&#xff0c;升级起来会非常方便&#xff0c;灵活性好。绝大多数的私有协议传输层都基于TCP/IP…