noi导刊《冲刺noip2010 七》翻转游戏题解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

主程序
#include <fstream> #include <string> #include <vector> using namespace std; ifstream fin("flip.in"); ofstream fou("flip.out"); int main(){ init(); ans=bfs(); if (ans>-1) fou<<ans<<endl; else fou<<"Impossible"<<endl; return 0; }
初始化
void init(){ string str; for (int i=0;i<4;i++){ fin>>str; for (int j=0;j<4;j++) sbegin=(sbegin<<1)+(str[j]=='b'?0:1); } //将长方形数字化b为0,w为1; dig[15]=1; for (int i=14;i>=0;i--) dig[i]=dig[i+1]<<1;//求各位的权值 deq.push_back(sbegin);//队列初始化, deq1.push_back(0); flag[sbegin]=true; }
广度搜素
int bfs(){ if (sbegin==0 || sbegin==send) return 0;//如果给定的状态就已经实现了目标就输出0 for (unsigned int head=0; deq.size()<65536 && head<deq.size();){ //如果队列空或所有状态都出现了结束,没有答案 for (int i=0;i<16;i++){ // 先任选一个位置待翻转 unsigned int now=deq[head]; //取队头元素 for (int j=0;j<5;j++){ //分别对第i个位置及其上下左右的位置翻转 int xx=i/4+fa[j][0],yy=i%4+fa[j][1]; if (xx>=0 && xx<4 && yy>=0 && yy<4 ) now^=(dig[i+fa[j][2]]); } if (now==0 || now==send) return(deq1[head]+1); // 到目标 if (flag[now])continue; // 如果重复则舍弃,否则入队并设置标志 deq.push_back(now); deq1.push_back(deq1[head]+1); flag[now]=true; } head++; } return(-1); }
数据结构
unsigned int sbegin=0,send=0x0000ffff,dig[16]; //dig[i]为第i位的权值,dig[0]为最高位。 int fa[5][3]={{0,0,0},{0,-1,-1},{0,1,1},{-1,0,4},{1,0,4}};// 翻动方案 bool flag[66000]={0};//判重标志数组最大65535 vector <unsigned int> deq;//广搜队列 vector <int> deq1; //deq1[i]为deq[i]的深度,即步数 int ans=0;
翻转游戏
题目描述




翻转游戏是在一个4格×4格的长方形上进行的,在长方形的16个格上每个格子都 放着一个双面的物件。每个物件的两个面,一面是白色,另一面是黑色,每个物 件要么白色朝上,要么黑色朝上,每一轮你只能翻3至5个物件,从而由黑到白的 改变这些物件上面的颜色,反之亦然。每一轮被选择翻转的物件遵循以下规则: 1、从16个物件中任选一个。 2、翻转所选择的物件的同时,所有与它相邻的左方物件、右方物件、上方物件 和下方物件(如果有的话),都要跟着翻转。 以下为例: bwbw wwww bbwb bwwb 这里"b"表示该格子放的物件黑色面朝上、"w"表示该格子放的物件白色朝上。 如果我们选择翻转第三行的第一个物件,那么格子状态将变为: bwbw bwww wwwb wwwb 游戏的目标是翻转到所有的物件白色朝上或黑色朝上。你的任务就是写一个程 序来求最少的翻转次数来实现这一目标。
输入输出格式


输入格式 输入文件flip.in包含4行,每行4个字符,每个 字符"w" 或 "b"表示游戏开始时格子上物件的状 态。 输出格式 输出文件flip.out仅一个整数,即从给定状态 到实现这一任务的最少翻转次数。如果给定的状 态就已经实现了目标就输出0,如果不可能实现目 标就输出"Impossible"。
输入输出样例
输入样例 bwwb bbwb bwwb bwww 输出样例 4

算法分析:



Biblioteka Baidu

求最少步数,广度搜索+位运算 将长方形数字化(b为0,w为1); 输入样例 bwwb bbwb bwwb bwww 转化为unsigned int sbegin=(0110 0010 0110 0111)2 各位对应权值(由高位到低位)为 dig{32768,16384,8192,4096,2048,1024,512,256,128, 64,32,16,8,4,2,1) 对x的第i位(从高位到低位0~15)取反为 x^dig[i] ,即异或运算
相关文档
最新文档