poj 1166 The Clocks 记录路径的广搜

题意:

给9个时钟的初始状态,和一些对某几个钟的操作,求最少经过几步能到目标状态(全指向12点)。

分析:

明显的广搜,但实现起来的细节要注意:1.因为要记录路径,所以要在整个程序执行过程中扩展出的节点在输出路径前不能销毁, 故采用静态内存分配的方法(开node[600000],用get_node()创建节点。2.queue<node>比queue<int>要多花1别的时间。

//poj 1166
//sep9
#include <iostream>
#include <queue>
using namespace std;
char move[10][8]={"ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"};
int vis[1000000],idx;
int ans[10000];
struct NODE
{
	int state,pre,move_used,idx;
}node[600000];

queue<int> q;

NODE get_node(int sta,int pre,int moves)
{
	node[idx].state=sta;
	node[idx].pre=pre;
	node[idx].move_used=moves;
	node[idx].idx=idx;
	return node[idx++];
}

int main()
{
	int a[10],b[10],ini_state=0;
	idx=0;
	memset(vis,0,sizeof(vis));
	while(!q.empty()) q.pop();
	for(int i=0;i<9;++i)
		scanf("%d",&a[i]);
	for(int i=8;i>=0;--i)
		ini_state=ini_state*4+a[i];
	NODE p=get_node(ini_state,-1,0);
	vis[p.state]=1;
	q.push(p.idx);
	int target_idx;
	while(!q.empty()){
		int x=q.front();q.pop();
		if(node[x].state==0){
	 		target_idx=node[x].idx;
	 		break;
		}
		int tmp=node[x].state;
		for(int i=0;i<9;++i){
			a[i]=tmp%4;
			tmp/=4;
		}
		for(int i=0;i<9;++i){
			for(int j=0;j<9;++j)
				b[j]=a[j];
			for(int j=0;move[i][j]!='\0';++j)
				b[move[i][j]-'A']=(a[move[i][j]-'A']+1)%4;
			int ns=0;
			for(int j=8;j>=0;--j)
				ns=ns*4+b[j];
			if(vis[ns]==0){
				NODE np=get_node(ns,node[x].idx,i+1);
				q.push(np.idx);
				vis[ns]=1;
			}
		}
	}
	int x=0;
	while(target_idx!=0){
		ans[x++]=node[target_idx].move_used;
		target_idx=node[target_idx].pre;
	}
	for(int i=x-1;i>=0;--i)
		printf("%d ",ans[i]);
	return 0;
} 
时间: 2024-10-06 01:14:54

poj 1166 The Clocks 记录路径的广搜的相关文章

POJ 3414 Pots 记录路径的广搜

Description You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i)        fill the pot i (1 ≤ i ≤ 2) from the tap; DROP(i)      empty the pot i to the drain; POUR(i,j)    pour from

POJ 1166 The Clocks (爆搜 || 高斯消元)

题目链接 题意: 输入提供9个钟表的位置(钟表的位置只能是0点.3点.6点.9点,分别用0.1.2.3)表示.而题目又提供了9的步骤表示可以用来调正钟的位置,例如1 ABDE表示此步可以在第一.二.四.五个钟调正,如原来是0点,那么调正后为3点.问经过那些步骤可以导致9个钟的位置都在0点. 分析: 这个本来是一个高斯消元的题目,但是 听说周期4不是素数, 求解过程中不能进行取余.因为取余可能导致解集变大. 不过也有用高斯消元做的,下面是用高斯消元的分析 ” Discuss也有人讨论了,4不是质数

POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)

根据题意可构造出方程组,方程组的每个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = sum + 4*k,exgcd求出符合范围的x9,其他方程在代入已知的变量后格式亦如此. 第一发Gauss,蛮激动的. #include <algorithm> #include <iostream> #include <cstring> #include <cstd

Charlie&#39;s Change POJ - 1787 (完全背包+记录路径)

完全背包输出路径:对于每一次更新记录一下路径:注意钱币个数: dp[i][0]代表在空间为i时需要多少枚钱币 dp[i][1]用来记录路径 cheek[j]用来记录在j时用了多少i枚钱币 思路在代码中: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define mem(a,b) memset(a,b,sizeof

poj 1166 The Clocks (暴搜)

The Clocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15944   Accepted: 6493 Description |-------| |-------| |-------| | | | | | | | |---O | |---O | | O | | | | | | | |-------| |-------| |-------| A B C |-------| |-------| |-------|

(poj)3414 Pots (输出路径的广搜)

Description You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap; DROP(i) empty the pot i to the drain; POUR(i,j) pour from pot i to pot j

Pots POJ - 3414 (搜索+记录路径)

Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22688   Accepted: 9626   Special Judge Description You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i)        f

poj 2251 Dungeon Master(简单三维广搜)

题意: 之前做过的所有题都是   在一个平面   上搜索 . 本题很新,在一个三维空间里 ,首先   l  x  y   分别代表 l 层   每一层有 x 行   y 列 问从 S 开始   走到 E   最小步是多少    显然用广搜,只是多了一个向上向下的搜索. 注意: 所谓广搜  ,是一层一层的搜,  每一层其步数是一样的   ,可以通过建立一个数组存步数 ,也可以 将步数同时存入队列中 另外搜过的要做标记, 在做标记时  尽量要在里面做标记(就是每搜过一个点就  立马 将之标记)不然一

Poj 1166 The Clocks(bfs)

题目链接:http://poj.org/problem?id=1166 思路分析:题目要求求出一个最短的操作序列来使所有的clock为0,所以使用bfs: <1>被搜索结点的父子关系的组织: 在bfs中,队列中存储着解答树中搜索过的结点,并且每个结点都可以使用它在队列中的位置作为其唯一的ID: 另外,使用另一个数组存储结点的父节点和从父节点到该节点的操作,同样的,使用结点在队列中的位置作为该节点的ID: 这种方法类似于并查集的方法,使用多个线性数组来模拟树的结构:这里模拟解答树中搜索过的结点构