题意:给你一个骰子的初始状态和可以进行的四种操作,求从初始状态到目标状态的最少操作次数

题目本身很简单,bfs即可。但是因为骰子有六个面,搜索判重和记录状态比较麻烦。这时候就需要神器STL了。

 #include <iostream>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std; struct node
{
vector<int> seq;
int step;
node(vector<int> x,int m):seq(x),step(m)
{}
}; int a[],b[];
vector<int> A;
vector<int> y;
//queue<node> Q;
map<vector<int>,int> M;
bool ok; void writeln(vector<int> x,node y)
{
for (int i=;i<;i++)
cout<<x[i]<<" ";
cout<<" - "<<y.step<<endl;
} bool satisfy()
{
for (int i=;i<;i++)
if (y[i]!=b[i]) return false;
ok=true;
return true;
} void lft()
{
vector<int> t;
t=y;
y[]=t[]; y[]=t[]; y[]=t[];
y[]=t[]; y[]=t[]; y[]=t[];
}
void rht()
{
vector<int> t;
t=y;
y[]=t[]; y[]=t[]; y[]=t[];
y[]=t[]; y[]=t[]; y[]=t[];
}
void fnt()
{
vector<int> t;
t=y;
y[]=t[]; y[]=t[]; y[]=t[];
y[]=t[]; y[]=t[]; y[]=t[];
}
void bak()
{
vector<int> t;
t=y;
y[]=t[]; y[]=t[]; y[]=t[];
y[]=t[]; y[]=t[]; y[]=t[];
} bool same()
{
for (int i=;i<;i++)
if (a[i]!=b[i]) return false;
return true;
} int main()
{
//freopen("in.txt","r",stdin); while (cin>>a[])
{
A.clear();
M.clear();
//Q.clear();
queue <node> Q;
ok=false; A.push_back(a[]);
for (int i=;i<;i++)
{
cin>>a[i];
A.push_back(a[i]);
}
for (int i=;i<;i++)
cin>>b[i];
if (same())
{
cout<<<<endl;
continue;
} Q.push(node(A,));
//int nm=1;
M.insert(pair<vector<int>,int>(A,)); while (!Q.empty())
{
node tmp=Q.front();
Q.pop();
int st=tmp.step;
st++;
y=tmp.seq;
//writeln(y,tmp); ////////
if (satisfy())
{
cout<<st-<<endl;
break;
}
/*
if (st>55)
{
cout<<-1<<endl;
break;
}*/
for (int tm=;tm<=;tm++)
{
if (tm==)
{
y=tmp.seq;
lft();
if (!M.count(y))
{
M.insert(pair<vector<int>,int>(y,));
Q.push(node(y,st));
}
}
if (tm==)
{
y=tmp.seq;
rht();
if (!M.count(y))
{
M.insert(pair<vector<int>,int>(y,));
Q.push(node(y,st));
}
}
if (tm==)
{
y=tmp.seq;
fnt();
if (!M.count(y))
{
M.insert(pair<vector<int>,int>(y,));
Q.push(node(y,st));
}
}
if (tm==)
{
y=tmp.seq;
bak();
if (!M.count(y))
{
M.insert(pair<vector<int>,int>(y,));
Q.push(node(y,st));
}
}
}
}
if (!ok) cout<<-<<endl;
} }

本题中用到的操作:

用map作为哈希表判重:

map<vector<int>,int>,这样就把一个vector容器和一个整数关联起来了。

map对象的.count(x)函数:返回x在哈希表中的出现次数,未出现则返回0。用这个函数就可以判重了。

queue:队列

注意queue和stack没有.clear()函数,所以用完之后没法清空,只能建一个新的(三次都WA到这里了,对拍时才发现T^T)

还有结构体声明里面的node(vector<int> x,int m)那个东西是结构体构造函数,neopenx大神教的,可以避免代码太屎

附上neopenx大神的AC代码,Orz

 #include "cstdio"
#include "queue"
#include "vector"
#include "map"
using namespace std;
int a[],b[];
vector<int> B;
map<vector<int>,int> HASH;
bool ok=false;
struct node
{
vector<int> X;
int num;
node(vector<int> x,int n): X(x),num(n) {}
};
void bfs()
{
vector<int> A;
for(int i=;i<=;i++) A.push_back(a[i]);
if(A==B) {printf("%d\n",);ok=true;return;}
queue<node> Q;Q.push(node(A,));
while(!Q.empty())
{
node x=Q.front();Q.pop();
//if(x.num>=8) continue; //没必要对dep剪枝了,目测数据在dep=4的时候,就能全部被hash掉
vector<int> tt=x.X;
for(int s=;s<;s++)
{
int flag=x.num;
if(s==)
{
int a=tt[],b=tt[],c=tt[],d=tt[];
vector<int> C;
C.push_back(c);C.push_back(d);C.push_back(b);C.push_back(a);
C.push_back(tt[]);C.push_back(tt[]);
if(C==B)
{
printf("%d\n",++flag);
ok=true;
return;
}
else
{
if(HASH.count(C)) continue;
else
{
HASH[C]=;
Q.push(node(C,++flag));
}
}
}
if(s==)
{
int a=tt[],b=tt[],c=tt[],d=tt[];
vector<int> C;
C.push_back(d);C.push_back(c);C.push_back(a);C.push_back(b);
C.push_back(tt[]);C.push_back(tt[]);
if(C==B)
{
printf("%d\n",++flag);
ok=true;
return;
}
else
{
if(HASH.count(C)) continue;
else
{
HASH[C]=;
Q.push(node(C,++flag));
}
}
}
if(s==)
{
int a=tt[],b=tt[],c=tt[],d=tt[];
vector<int> C;
C.push_back(c);C.push_back(d);
C.push_back(tt[]);C.push_back(tt[]);
C.push_back(b);C.push_back(a);
if(C==B)
{
printf("%d\n",++flag);
ok=true;
return;
}
else
{
if(HASH.count(C)) continue;
else
{
HASH[C]=;
Q.push(node(C,++flag));
}
}
}
if(s==)
{
int a=tt[],b=tt[],c=tt[],d=tt[];
vector<int> C;
C.push_back(d);C.push_back(c);
C.push_back(tt[]);C.push_back(tt[]);
C.push_back(a);C.push_back(b);
if(C==B)
{
printf("%d\n",++flag);
ok=true;
return;
}
else
{
if(HASH.count(C)) continue;
else
{
HASH[C]=;
Q.push(node(C,++flag));
}
}
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d",&a[]))
{
for(int i=;i<=;i++)
scanf("%d",&a[i]);
for(int i=;i<=;i++)
{
scanf("%d",&b[i]);
B.push_back(b[i]);
}
bfs();
if(!ok) printf("-1\n");
B.clear();
HASH.clear();
ok=false;
}
}

2014ACMICPC西安网赛1006的更多相关文章

  1. 2017 ACM-ICPC西安网赛B-Coin

    B-Coin Bob has a not even coin, every time he tosses the coin, the probability that the coin's front ...

  2. HDU 5047 Sawtooth(大数模拟)上海赛区网赛1006

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5047 解题报告:问一个“M”型可以把一个矩形的平面最多分割成多少块. 输入是有n个“M",现 ...

  3. 2013长春网赛 1006 hdu 4764 Stone(巴什博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 题意:Tang 和 Jiang 玩一个游戏,轮流写下一个数,Tang先手,第一次Tang只能写[ ...

  4. hdu 5011 nim博弈 (2014西安网赛E题)

    n堆石子,每次可以选一堆取走至少一个,之后你可以不操作或者把该堆石子分成两堆,每堆至少一个,和还是原来(取完石子后)的石子个数. Sample Input1121 131 2 3 Sample Out ...

  5. hdu 5007 水题 (2014西安网赛A题)

    题意:出现Apple.iPod.iPhone.iPad时输出MAI MAI MAI!,出现Sony,输出SONY DAFA IS GOOD! Sample InputApple bananaiPad ...

  6. ACM学习历程—HDU 5012 Dice(ACM西安网赛)(bfs)

    Problem Description There are 2 special dices on the table. On each face of the dice, a distinct num ...

  7. ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)

    Description There is a special number sequence which has n+1 integers. For each number in sequence, ...

  8. ACM学习历程——HDU5017 Ellipsoid(模拟退火)(2014西安网赛K题)

    ---恢复内容开始--- Description Given a 3-dimension ellipsoid(椭球面) your task is to find the minimal distanc ...

  9. 大连网络赛 1006 Football Games

    //大连网络赛 1006 // 吐槽:数据比较水.下面代码可以AC // 但是正解好像是:排序后,前i项的和大于等于i*(i-1) #include <bits/stdc++.h> usi ...

随机推荐

  1. ZGrapher 画函数曲线图的工具

    可以下载个绿色版,我下载的是 ZGrapher 1.4 绿色版.下面先看下图出来的图: 然后可以在“file"->"Save as Picture ..." -&g ...

  2. Android 动态加载 (二) 态加载机制 案例二

    探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...

  3. 【MFC】序列化(Serialize)、反序列化(Deserialize)

    1.首先在头文件里面声明 DECLARE_SERIAL(CSelectionSerial) 2.重写CObject的Serialize函数 virtual void Serialize(CArchiv ...

  4. Linux及安全——Linux基础实践

    Linux及安全——Linux基础实践 一.实践一:掌握软件源的维护方法,配置系统使用教育网内的软件源镜像.掌握通过软件源来查找,安装,卸载,更新软件的方法. 1.软件源的维护方法 Ubuntu的软件 ...

  5. Linux基础入门(20135207 王国伊)

    实验一  Linux系统简介 一.实验心得 首个实验是简单介绍了Linux系统的简介,了解Linux系统的历史和发展.使我受益匪浅 实验二  基本概念及操作 一.学习目标 1.实验楼环境介绍 2.常用 ...

  6. mysql命令行

    mysql -u root -p create database bookstore; drop database bookstore; use bookstore create table user ...

  7. Scala学习笔记(六):Scala程序

    想要编写能够独立运行的Scala程序,就必须创建有main方法(仅带一个参数Array[String],且结果类型为Unit)的单例对象. 任何拥有合适签名的main方法的单例对象都可以用来作为程序的 ...

  8. struts2+Hibernate实现用户登陆功能

    实现的功能,在登陆页面输入Username和PassWord后,将username和password通过Hibernate匹对数据库是否含有一样的username和password,若有则登陆进去,若 ...

  9. 每天一个linux命令(45):route命令

    Linux系统的route 命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需 要一台连接两个网络的路由器 ...

  10. beta版本贡献率

    队名:攻城小分队 031302410 郭怡锋 : 占比:50% 031302411 洪大钊: 占比:30% 031302206 陈振贵: 占比:10% 031302416 黄伟祥: 占比:10%