关闭

POJ3414Pots(AC)

184人阅读 评论(0) 收藏 举报
Pots
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 12571   Accepted: 5300   Special Judge

Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤ i ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to pot j; after this operation either the potj is full (and there may be some water left in the poti), or the poti is empty (and all its contents have been moved to the potj).

Write a program to find the shortest possible sequence of these operations that will yield exactlyC liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, andC. These are all integers in the range from 1 to 100 andC≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operationsK. The followingK lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input

3 5 4

Sample Output

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

 

<pre class="cpp" name="code">#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

/*对于这道题有个疑问是FILL(i)这个第i个盆弄满,那到底多少毫升算是弄满,是不是这样的3 5 4中的3 5 分别表示第一个的体积是3,第2个的体积是5,应该是这样的,要不然没别的解释*/
/*上面的理解是对的,而且这道题还要输出路径的,这个也要注意的,不光光是输出最小步数的*/

//这个还要输出路径的,要注意,输出路径也是有难度的

//这个是只要任意一个得到残余水量就行,自己开始理解的不对,以为2个都要达到----这个是看了提示题目之前就看的,所以一直记的是2个都达到要求的水量,是不对的

//同时还有一个要输出impossible的情况

/*第一次提交Runtime Error运行时出错了,自己没有做visit的操作,这个是看了说明之后才知道要设visit的,因为自己认为相同的操作是可以的,大错误,直接导致都溢出了
  但是直接用visit数组又不对,这样最大就6个操作肯定不对*/
/*怎么进行控制呢。。。本题关键就是这个visit到底是设的什么?ttp://blog.csdn.net/lyy289065406/article/details/6647930 这里讲了这题的2个难点,其中第2个就是状态 
  记录,自己一直没弄好的这个后来还是看了很多参考之后,然后得出的状态是如果pot1和pot2残留的水量曾经有过,就不要操作了,否则就是多余操作的,,然后就AC了*/

/*测试数据
1 5 2
3 5 4*/

/*POJ AC*/

#define MAXINT 1000

#define MAX(a,b)  ((a)<(b)?(b):(a))

int pot1 = 0; //pot1最多可以放的液体数
int pot2 = 0;
int aim = 0;
int back = 0;//采用只有back不用front的方法,BFS要慢慢用这种方法,这样可以有效的减少que的空间大小,这题不适合用覆盖的方法,因为要求路径啊
int front= 0;

#define FILL (1)
#define POUR (2)
#define DROP (3)

typedef struct nodes
{
	char operation[20]; //存放动作
	int src;   //源
	int des;  //目的 比如POUR(2,1),2-src,1-des
	int step;
	int pot1;
	int pot2;  //存放当前各pot中的液体数,也就是做了本次操作后各pot的液体数
	int fatherindex;
}node;

node que[MAXINT];
int  visit[MAXINT][MAXINT];
int ans = 0;

void insert(int type, int p1, int p2, int src, int des, int step,int fatherIndex)
{
	if (FILL == type)
	{
		que[back].operation[0] = 'F';
		que[back].operation[1] = 'I';
		que[back].operation[2] = 'L';
		que[back].operation[3] = 'L';
	}
	else if (DROP == type)
	{
		que[back].operation[0] = 'D';
		que[back].operation[1] = 'R';
		que[back].operation[2] = 'O';
		que[back].operation[3] = 'P';
	}
	else
	{
		que[back].operation[0] = 'P';
		que[back].operation[1] = 'O';
		que[back].operation[2] = 'U';
		que[back].operation[3] = 'R';
	}
	que[back].src         = src;
	que[back].des         = des;
	que[back].fatherindex = fatherIndex;
	que[back].pot1        = p1;
	que[back].pot2        = p2;
	que[back++].step      = step;
	return;
}

void GetPath(int index,int father)
{
	int i = 0;
	int num = 0;
	int path[10000]; //记录Index
	path[num++] = index;
	while (-1 != father)
	{
		index = father;
		path[num++] = index;
		father = que[father].fatherindex;
	}
	for (i = (num-1); i > 0;i--)
	{
		if (('D' == que[path[i]].operation[0]) || ('F' == que[path[i]].operation[0]))
		{
			printf("%c%c%c%c(%d)\n", que[path[i]].operation[0], que[path[i]].operation[1], que[path[i]].operation[2], que[path[i]].operation[3], que[path[i]].src);
		}
		else
		{
			printf("%c%c%c%c(%d,%d)\n", que[path[i]].operation[0], que[path[i]].operation[1], que[path[i]].operation[2], que[path[i]].operation[3], que[path[i]].src, que[path[i]].des);
		}
	}
}



void bfs()
{
	int fix1 = 0;
	int fix2 = 0;//存放的pot中液体数
	int p1 = 0;
	int p2 = 0;
	int sp   = 0;
	int i = 0;
	int father = -1;
	int mark = 0;
	//每个操作可以有FILL(1),FILL(2),POUR(2,1),POUR(1,2),DROP(1),DROP(2) 应该是有这么多操作的可能性
	//开始的时候只可能由FILL的操作,不可能有POUR和DROP,因为刚开始的时候都是空的
	for (i = 1; i<=2; i++)
	{
		que[back].operation[0] = 'F';
		que[back].operation[1] = 'I';
		que[back].operation[2] = 'L';
		que[back].operation[3] = 'L';
		que[back].src          = i;
		que[back].fatherindex  = -1;
		if (1 == i)
		{
			que[back].pot1 = pot1;
			que[back].pot2 = 0;
			visit[pot1][0] = 1;
		}
		else
		{
			que[back].pot1 = 0;
			que[back].pot2 = pot2;
			visit[0][pot2] = 1;
		}
		que[back++].step = 1;
	}

	while (front < back)
	{
		fix1 = que[front].pot1;
		fix2 = que[front].pot2;
		sp    = que[front].step;
		father = front;

		if ((aim == fix1) || (aim == fix2))
		{
			ans = que[front].step;
			printf("%d\n", ans);
			GetPath(front ,father);
			return;
		}

		//原来以为之前是什么操作,后面可能就不会有相同的操作,其实这是不对的,fill操作也可以紧跟fill操作
		//因为fill(1)后面可以是fill(2),而且不区分代码也会简洁一点,否则会有很多重复代码
		//drop操作
		for (i = 1; i <= 2; i++)
		{
			if ((1 == i) && (fix1 >0))//drop(1)
			{
				p1 = 0;
				p2 = fix2;
				if (0 == visit[p1][p2])
				{
					insert(DROP, p1, p2, i, 0, sp + 1, father);
					//SetVisit(DROP, i, 0);
					visit[p1][p2] = 1;
				}
				
			}
			else if ((2 == i) && (fix2 >0))//drop(2)
			{
				p1 = fix1;
				p2 = 0;

				if (0 == visit[p1][p2])
				{
					insert(DROP, p1, p2, i, 0, sp + 1, father);
					visit[p1][p2] = 1;
				}
			}
		}

		//pour操作
		for (i = 1; i <= 2; i++)
		{
			if (1 == i) //pour(1,2)
			{
				if (fix1 > 0)
				{
					//1往2里面倒
					if ((pot2 - fix2) >= fix1) //p1都倒完了
					{
						p2 = fix2 + fix1;
						p1 = 0;
					}
					else
					{
						p2 = pot2;
						p1 = fix1 + fix2 - pot2;
					}

					if (0 == visit[p1][p2])
					{
						insert(POUR, p1, p2, 1, 2, sp + 1, father);
						//SetVisit(POUR, 1, 2);
						visit[p1][p2] = 1;
					}
				}
			}
			else
			{//pour(2,1)

				/*2往1里面倒*/
				if (fix2 > 0)
				{
					if ((pot1 - fix1) >= fix2)
					{
						p1 = fix1 + fix2;
						p2 = 0;
					}
					else
					{
						p1 = pot1;
						p2 = fix2 + fix1 - pot1;
					}

					if (0 == visit[p1][p2])
					{
						insert(POUR, p1, p2, 2, 1, sp + 1, father);
						//SetVisit(POUR, 2, 1);
						visit[p1][p2] = 1;
					}
				}
			}
			
		}

		//FILL操作
		for (i = 1; i <= 2; i++)
		{
			if ((1 == i) && (fix1 <pot1))//fill(1)
			{
				p1 = pot1;
				p2 = fix2;
				if (0 == visit[p1][p2])
				{
					insert(FILL, p1, p2, i, 0, sp + 1, father);
					//SetVisit(FILL, i, 0);
					visit[p1][p2] = 1;
				}
				
			}
			else if ((2 == i) && (fix2 <pot2))//fill(2)
			{
				p1 = fix1;
				p2 = pot2;
				if (0 == visit[p1][p2])
				{
					insert(FILL, p1, p2, i, 0, sp + 1, father);
					//SetVisit(FILL, i, 0);
					visit[p1][p2] = 1;
				}				
			}
		}

		front++;
	}

	printf("impossible\n");
	return;
}

void init()
{
	int i = 0;
	int j = 0;
	for (i = 0; i < MAXINT;i++)
	{
		for (j = 0; j < MAXINT; j++)
		{
			visit[i][j] = 0;
		}
	}
	ans = 0;
	return;
}

int main()
{
	int maxint = 0;
	freopen("input.txt","r",stdin);
	scanf("%d %d %d", &pot1, &pot2,&aim);
	init();
	maxint = MAX(pot1, pot2); //这个是看了discuss后加的,最开始觉得不需要加这个判断,输入会控制的,还是要加下,否则用3 4 5 我的堆栈直接爆了
	if (aim <= maxint)
	{
		bfs();
	}
	else
	{
		printf("impossible\n");
	}
	
	return 0;
}


   
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

80211(b/a/n/ac)速率介绍

80211各协议速率介绍及由来
  • cuijiyue
  • cuijiyue
  • 2016-05-04 23:16
  • 7868

802.11 a/b/g/n/ac 是什么以及它们有什么区别

首先802.11 是一种无线局域网标准。 802.11 a/b/g/n/ac 都是由802.11 发展而来的。不同的后缀代表着不同的物理层标准工作频段和不同的传输速率,也就是说它们的物理层和传输速度...
  • briant_ccj
  • briant_ccj
  • 2016-01-09 11:24
  • 23249

ac自动机最详细的讲解,让你一次学会ac自动机。

在没学ac自动机之前,觉得ac自动机是个很神奇,很高深,很难的算法,学完之后发现,ac自动机确实很神奇,很高深,但是却并不难。 我说ac自动机很神奇,在于这个算法中失配指针的妙处(好比kmp算法中的...
  • creatorx
  • creatorx
  • 2017-05-02 19:51
  • 14682

POJ3414-Pots

  • 2011-07-31 22:40
  • 9KB
  • 下载

poj 3414 Pots 广度优先搜索

Description You are given two pots, having the volume of A and B liters respectively. The followi...
  • u013087645
  • u013087645
  • 2014-07-30 00:53
  • 662

POJ 3414 Pots 我没有用广搜做

Pots Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total Sub...
  • J1nAB1n9
  • J1nAB1n9
  • 2017-08-06 19:30
  • 106

[kuangbin带你飞]专题一 简单搜索H - Pots(POJ 3414)

H - Pots Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u S...
  • ZZ_AC
  • ZZ_AC
  • 2015-11-10 21:49
  • 462

POJ 3414 Pots 解题报告(搜索)

题目大意:两个杯子,容量为A,B,每次可以装满,倒掉,或者A倒进B或者B倒进A,共计六种操作。问如何得到容量C并且打印此过程。     解题报告:每次六种操作,凭感觉也知道是广搜。     难点有两个...
  • kbdwo
  • kbdwo
  • 2013-08-04 13:17
  • 962

POJ 3414 Pots(简单模拟+dfs)

Description 给你两个容器,求出获得指定量水的步骤 三个操作 FILL(A):将A容器装满水 DROP(A):将A容器中的水倒出 POUR(A,B):将A容器中的水全部倒...
  • V5ZSQ
  • V5ZSQ
  • 2015-07-14 09:30
  • 235

POJ3414 Pots

= =BFS水题 #include #include #include #include #include using namespace std; int A,B,C; class node { ...
  • zhangwei1120112119
  • zhangwei1120112119
  • 2013-04-23 16:08
  • 365
    个人资料
    • 访问:39895次
    • 积分:1175
    • 等级:
    • 排名:千里之外
    • 原创:67篇
    • 转载:52篇
    • 译文:3篇
    • 评论:6条
    博客专栏
    最新评论