【USACO】时钟(BFS)
2018-03-26 21:32
204 查看
题目描述
考虑将如此安排在一个 3 x3 行列中的九个时钟:|-------| |-------| |-------|| | | | | | |
|---O | |---O | | O |
| | | | | |
|-------| |-------| |-------|
A B C
|-------| |-------| |-------|
| | | | | |
| O | | O | | O |
| | | | | | | | |
|-------| |-------| |-------|
D E F
|-------| |-------| |-------|
| | | | | |
| O | | O---| | O |
| | | | | | | |
|-------| |-------| |-------|
G H I目标要找一个最小的移动顺序次将所有的指针指向12点。下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。移动方法 受影响的时钟
1 ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI
Example
9 9 12 9 12 12 9 12 12 12 12 12 12 12 126 6 6 5 -> 9 9 9 8-> 9 9 9 4 -> 12 9 9 9-> 12 12 126 3 6 6 6 6 9 9 9 12 9 9 12 12 12 [但这可能不是正确的方法,请看下面]
输入
第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。数字的含意和上面第一个例子一样。输出
单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。 如果有多种方案,输出那种使的连接起来数字最小的方案。(举例来说5 2 4 6 < 9 3 1 1)。样例输入
9 9 12
6 6 6
6 3 6
样例输出
4 5 8 9
提示
思路:很明显的BFS,用ans数组记录一下方法,用pre数组记录一下到当前点的路径,判断某个状态是否已经出现过,即vis过,转化成4进制的9位数,因为只有4种状态,则可用数组存下了。最后递归输出就好了。代码:#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)
const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e7+5;
int vis
;
int b[10];
int pre
;
int ans
;
int res;
int dir[10][10]={
0,0,0,0,0,0,0,0,0,0,
0,1,1,0,1,1,0,0,0,0,
0,1,1,1,0,0,0,0,0,0,
0,0,1,1,0,1,1,0,0,0,
0,1,0,0,1,0,0,1,0,0,
0,0,1,0,1,1,1,0,1,0,
0,0,0,1,0,0,1,0,0,1,
0,0,0,0,1,1,0,1,1,0,
0,0,0,0,0,0,0,1,1,1,
0,0,0,0,0,1,1,0,1,1
};
int cal(int a[])
{
int sum=0;
int tmp=1;
for(int i=1;i<=9;i++)
{
sum+=a[i]*tmp;
tmp*=4;
}
return sum;
}
struct node
{
int a[10];
int idx; //索引
};
void bfs()
{
queue<node>q;
node now,next;
MEM(vis,0);
int x=cal(b);
vis[x]=1;
for(int i=1;i<=9;i++)
now.a[i]=b[i];
int cnt=0;
now.idx=0;
pre[now.idx]=-1;
q.push(now);
while(!q.empty())
{
now=q.front();
q.pop();
bool flag=true;
for(int i=1;i<=9;i++)
if(now.a[i]!=3)
flag=false;
if(flag)
{
res=now.idx;
return;
}
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
4000
next.a[j]=(now.a[j]+dir[i][j])%4;
int tmp=cal(next.a);
if(!vis[tmp])
{
cnt++;
vis[tmp]=1;
next.idx=cnt;
pre[next.idx]=now.idx;
ans[next.idx]=i;
q.push(next);
}
}
}
}
void output(int xx)
{
if(pre[xx]==-1)
{
return ;
}
output(pre[xx]);
printf("%d ",ans[xx]);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
std::ios::sync_with_stdio(false);
int n;
while(~scanf("%d",&b[1]))
{
for(int i=2;i<=9;i++)
scanf("%d",&b[i]);
bool flag=true;
for(int i=1;i<=9;i++)
{
b[i]=b[i]/3-1;
if(b[i]!=3)
flag=false;
}
if(flag)
{
printf("\n");
continue;
}
bfs();
output(pre[res]);
printf("%d\n",ans[res]);
}
return 0;
}
相关文章推荐
- USACO Overfencing,BFS,FloodFill
- [USACO2004][poj1985]Cow Marathon(2次bfs求树的直径)
- [USACO13FEB]Tractor【二分 + BFS】
- usaco 1.4 clocks...bfs...
- 【宽搜】The Clocks 时钟 (Usaco_Training 1.4)
- bzoj 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛(BFS)
- [luoguP3110] [USACO14DEC]驮运Piggy Back(SPFA || BFS)
- USACO2.42Overfencing(bfs)
- BZOJ 1627: [Usaco2007 Dec]穿越泥地( BFS )
- USACO 2007 Dec Silver Mud Puddles bfs or A-star
- 【BZOJ】3299: [USACO2011 Open]Corn Maze玉米迷宫(bfs)
- USACO 2.14 Healthy Holsteins(BFS)
- bzoj 3383: [Usaco2004 Open]Cave Cows 4 洞穴里的牛之四(set+BFS)
- Starry Night_usaco 5.1_bfs+暴力
- bzoj 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场【bfs】
- USACO:1.4.2 The Clocks 时钟(IOI 94) 解析
- USACO section 2.4 Overfencing(dfs+bfs)
- BZOJ_1671_[Usaco2005 Dec]Knights of Ni 骑士_BFS
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- bzoj 1632: [Usaco2007 Feb]Lilypad Pond【bfs】