码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3414 Pots

时间:2015-08-02 23:31:41      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

Pots

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 pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

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

Input


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

Output


The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation.
Sample Input
3 5 4

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

Source

Northeastern Europe 2002, Western Subregion

题意:倒水 6种操作,分别是1:向1杯装满水;2:向2杯装满水;3:1杯水倒入2杯;4:2杯水倒入1杯;5:1杯水倒出;6:2杯水倒出
思路:简单BFS+回溯 广搜时借用节点下标,记录父亲节点,同时记录操作对应的数字,以及终点节点  从终点节点回溯,打印路径  
#include <cstdio>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <vector>
using  namespace std ;
int a , b  , c ;
int num , flag  ;               //num 记录搜索步数 , flag 记录终点搜索步数
int ans[101][101] ;            //记录步数
struct next {                   
    int op ;                   //操作
    int par ;                  //父亲
} nn[10001] ;                  
void dfs( int flag ) {         //深搜打印路径
    if( flag > 0 ) { dfs(nn[flag].par) ;}
            if(nn[flag].op == 1 ) cout << "FILL(1)" << endl;
            else if(nn[flag].op == 2 ) cout << "FILL(2)" << endl;
            else if(nn[flag].op == 3 ) cout << "POUR(1,2)" << endl;
            else if(nn[flag].op == 4 ) cout << "POUR(2,1)" << endl;
            else if(nn[flag].op == 5 ) cout << "DROP(1)" << endl;
            else if(nn[flag].op == 6 ) cout << "DROP(2)" << endl;
}
bool bfs() {                    
    memset(ans, 0 ,sizeof(ans)) ;
    ans[0][0] = 1;
    queue<int> A ;
    queue<int> B ;
    while(!A.empty()||!B.empty() ) {  
        A.pop() ;B.pop() ;
    }
    A.push(0) ;
    B.push(0) ;
    int time  = 0 , tempa , tempb ; //time 当前节点数
    while(!A.empty()) {
       int inita = A.front () ;
       int initb = B.front()  ;
        A.pop() ;B.pop() ;
                //FILL(1)
                tempa = a ;
                 tempb = initb ;
                if ( !ans[tempa][tempb] ) { //保证未访问过
                     A.push(tempa) ;
                     B.push(tempb) ;
                     ans[tempa][tempb]  = ans[inita][initb] +1 ;
                     nn[num].op = 1 ;       
                     nn[num++].par = time ; //记录父亲节点
                     if ( tempa==c || tempb==c ) {
                        flag = num-1 ;      //记录终点节点
                        break;
                     }
                }
                //FILL(2)
                tempa = inita ;
                tempb = b ;
                 if( !ans[tempa][tempb] ) {
                     A.push(tempa) ;
                     B.push(tempb) ;
                     ans[tempa][tempb]  = ans[inita][initb] +1;
                     nn[num].op = 2 ;
                     nn[num++].par = time ;
                     if(tempa==c||tempb==c) {
                        flag = num -1;
                        break ;
                     }
                }   
                //POUR(1,2) 
                if(inita <= b-initb) tempa = 0 ;  //倒完      
                else tempa = inita - ( b - initb) ;//倒部分
                    tempb = (initb + inita) ;   
                if(tempb> b) tempb = b ;            //小心溢出
                 if( !ans[tempa][tempb] ) {
                     A.push(tempa) ;
                     B.push(tempb) ;
                     ans[tempa][tempb]  = ans[inita][initb] +1;
                     nn[num].op = 3 ;
                     nn[num++].par = time ;
                     if(tempa==c||tempb==c) {
                        flag = num-1 ;
                        break ;
                     }
                }
                //POUR(2,1)
                if(initb <= a-inita) tempb = 0 ;
                else tempb = initb - ( a - inita) ;
                tempa = (initb + inita) ;
                if(tempa> a) tempa = a ;
                 if( !ans[tempa][tempb] ) {
                    A.push(tempa) ;
                    B.push(tempb) ;
                    ans[tempa][tempb]  = ans[inita][initb] +1;
                    nn[num].op = 4 ;
                     nn[num++].par = time ;
                    if(tempa==c||tempb==c) {
                        flag = num-1 ;
                        break ;
                        }
                }
                //DROP(1)
                tempa = 0 ;
                tempb = initb ;
                if( !ans[tempa][tempb] ) {
                    A.push(tempa) ;
                    B.push(tempb) ;
                    ans[tempa][tempb]  = ans[inita][initb] +1;
                    nn[num].op =5 ;
                     nn[num++].par = time ;
                    if(tempa==c||tempb==c) {
                        flag = num-1 ;
                        break;
                     }
                }
                //DROP(2)
                tempb = 0 ;
                tempa = inita ;
                 if( !ans[tempa][tempb] ) {
                    A.push(tempa) ;
                    B.push(tempb) ;
                    ans[tempa][tempb]  = ans[inita][initb] +1;
                    nn[num].op = 6 ;
                     nn[num++].par = time ;
                      if(tempa==c||tempb==c) {
                        flag = num-1 ;
                        break;
                     }
                }
                ++time ;        //记录节点数
    }
    if( flag ) {
            printf("%d\n",max(ans[tempa][tempb],ans[tempb][tempa])-1) ;//ans[0][0] = 1 , 故减之
            dfs(flag) ;
            return true ;
        }
    return false ;
}
int main( )  {
    while(~scanf("%d %d %d",&a,&b,&c) ) {
        num = 1 ;
        flag = 0;
        if(!bfs()) cout << "impossible"  << endl ;
    }
    return 0 ;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 3414 Pots

标签:

原文地址:http://blog.csdn.net/fzw_captain/article/details/47211217

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!