标题:求大神分析这个程序的原理
只看楼主
神话归来99
Rank: 1
等 级:新手上路
帖 子:5
专家分:5
注 册:2012-9-7
结帖率:0
已结贴  问题点数:20 回复次数:5 
求大神分析这个程序的原理
题目:
某人有12品脱的酒一瓶,想从中倒出6品脱,但他没有6品脱的容器,仅有一个8品脱和5品脱的容器,设计一个程序输出每一步的分法将啤酒分为两个6品脱。
代码  求大神分析
#include <iostream>
using namespace std;
int V[3]={12,8,5};
int src[6] ={0,0,1,1,2,2};
int dest[6]={1,2,0,2,0,1};
int record[100][3];
int rec_index=0;
void Pour(int state[],int a,int b)
{   
    int r=V[b]-state[b];   
    if(state[a]<r)
    {
        state[b]+=state[a];
        state[a]=0;
    }   
else
    {
    state[b]=V[b];
    state[a]-=r;
    }
}
void Output()
{   
    printf("    A    B    C\n");  
    for(int i=0;
    i<rec_index;++i)
    printf("%4d %4d %4d\n",record[i][0],record[i][1],record[i][2]);
    printf("\n\n");}void Record(int state[])
    {   
        record[rec_index][0]=state[0];   
        record[rec_index][1]=state[1];   
        record[rec_index][2]=state[2];   
        ++rec_index;}bool Exist(int state[])
        {   
            for(int i=0;i<rec_index;++i)
                if (state[0]==record[i][0]&& state[1]==record[i][1]&& state[2]==record[i][2])  
                    return true;   
                return false;
        }
        void Solve(int state[])
        {   
            int a=state[0],b=state[1],c=state[2];  
            Record(state);
            if(a==6 && b==6 && c==0) {Output();return;
            }   
            for(int i=0;i<6;++i)  
            {      
                if(state[src[i]]==0) continue;
                Pour(state,src[i],dest[i]);   
                if(!Exist(state))   
                {        
                    Solve(state);
                    --rec_index;  
                }        state[0]=a;state[1]=b;state[2]=c;
            }
        }
        int main()
        {   
            int init[3]={12,0,0};  
            Solve(init);   
            return 0;
}
搜索更多相关主题的帖子: include record 
2013-03-05 08:54
梦幻乐园
Rank: 2
等 级:论坛游民
帖 子:62
专家分:87
注 册:2012-10-25
得分:5 
比较难
2013-03-05 08:57
神话归来99
Rank: 1
等 级:新手上路
帖 子:5
专家分:5
注 册:2012-9-7
得分:0 
求讲解啊  
2013-03-05 09:05
pauljames
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:千里冰封
威 望:9
帖 子:1555
专家分:10000
注 册:2011-5-8
得分:5 
按照12 8 5排列好三个瓶子
1.从12往8里面倒满,这样三瓶为4,8,0
2.从8往5里面倒满,这样三瓶为4,3,5
3.从5里面往12倒,直到5和8里面的酒一样多,这样三瓶为6,3,3
4.把5的酒合并到8,就得到6,6,0

经常不在线不能及时回复短消息,如有c/单片机/运动控制/数据采集等方面的项目难题可加qq1921826084。
2013-03-06 07:37
party620
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:18
帖 子:696
专家分:2521
注 册:2013-1-31
得分:5 
支持4楼!!!
2013-03-06 09:25
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:5 
没细想,我就用最暴力的遍历法^_^,代码如下:
程序代码:
#include <map>
#include <vector>
#include <cstdio>
using namespace std;

void foo( int a, int b, int c, int step, map<int,int>& steps, vector<int> myhistory, vector<int>& history )
{
    myhistory.push_back( a+13*b+13*9*c );

    if( a==6 && b==6 )
    {
        if( history.empty() || myhistory.size()<history.size() )
            history = myhistory;
        return;
    }

    map<int,int>::iterator itor = steps.find(a+13*b+13*9*c);
    if( itor != steps.end() )
    {
        if( step < itor->second )
            itor->second = step;
        else
            return;
    }
    else
    {
        steps[a+13*b+13*9*c] = step;
    }

    if( a!=0 && b!=8 )
        foo( a+b<8?0:a+b-8, a+b<8?a+b:8, c, step+1, steps, myhistory, history );
    if( a!=0 && c!=5 )
        foo( a+c<5?0:a+c-5, b, a+c<5?a+c:5, step+1, steps, myhistory, history );
    if( b!=0 && a!=12 )
        foo( b+a<12?b+a:12, b+a<12?0:b+a-12, c, step+1, steps, myhistory, history );
    if( b!=0 && c!=5 )
        foo( a, b+c<5?0:b+c-5, b+c<5?b+c:5, step+1, steps, myhistory, history );
    if( c!=0 && a!=12 )
        foo( c+a<12?c+a:12, b, c+a<12?0:c+a-12, step+1, steps, myhistory, history );
    if( c!=0 && b!=8 )
        foo( a, c+b<8?c+b:8, c+b<8?0:c+b-8, step+1, steps, myhistory, history );
}

void bar()
{
    map<int,int> steps;
    vector<int> history;
    foo( 12, 0, 0, 0, steps, vector<int>(), history );

    for( vector<int>::const_iterator itor=history.begin(); itor!=history.end(); ++itor )
    {
        int n = *itor;
        printf( "%d/12 %d/8 %d/5\n", n%13, n/13%9, n/13/9 );
    }
}

int main()
{
    bar();

    return 0;
}
输出:
程序代码:
12/12 0/8 0/5
4/12 8/8 0/5
4/12 3/8 5/5
9/12 3/8 0/5
9/12 0/8 3/5
1/12 8/8 3/5
1/12 6/8 5/5
6/12 6/8 0/5

2013-03-06 12:37



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-399776-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024315 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved