| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4762 人关注过本帖
标题:砝码称重问题和分红酒问题
只看楼主 加入收藏
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
我的思路:

先把状态以四位数简记,再开一个 长度9000的数组记录最少次数,和一个队列记录状态,不知道对不对,代码先贴着
程序代码:
#include <stdio.h>

int front, rear;
int ss[9001] = {0};        //记录最少次数
int queue[9001] = {0};
int vol[] = {9, 7, 4, 2};

void InQueue(int n)
{    //入队列:当前状态为 n,将n下一步所有可能入队列
    int k = 0, temp;
    int i, j, a[4], tmp[12][4] = {0};

    a[0] = n / 1000;
    a[1] = n / 100 % 10;
    a[2] = n / 10 % 10;
    a[3] = n % 10;
    
    for (i = 0;i < 12;++i)
    {
        tmp[i][0] = a[0];
        tmp[i][1] = a[1];
        tmp[i][2] = a[2];
        tmp[i][3] = a[3];
    }

    for (i = 0;i < 4;++i)
    for (j = 0;j < 4;++j)
    {
        if (i == j || !a[i] || a[j] == vol[j])
            continue;
        if (a[i] + a[j] > vol[j])
        {
            tmp[k][i] = a[i]+a[j]-vol[j];
            tmp[k][j] = vol[j];
        }
        else
        {
            tmp[k][i] = 0;
            tmp[k][j] = a[i] + a[j];
        }
        ++k;
    }

    for (i = 0;i < k;++i)
    {
        temp = tmp[i][0]*1000+tmp[i][1]*100
            +tmp[i][2]*10+tmp[i][3];
        if (ss[temp] || temp == 9000)
            continue;
        queue[rear++] = temp;
        ss[temp] = ss[n] + 1;
    }
}
int OutQueue()
{    //出队列
    return queue[front++];
}
void init()
{
    int i;
    InQueue(9000);
    while (front != rear)
    {
        InQueue(OutQueue());
    }
    for (i = 0;i < 9000;++i)
    {
        if (!ss[i])    ss[i] = -1;
    }
}

int main()
{
    int a, b, c, d;
    init();
    while (scanf("%d,%d,%d,%d", &a, &b, &c, &d) == 4)
    {
        printf("%d\n", ss[a*1000+b*100+c*10+d]);
    }
    return 0;
}


[fly]存在即是合理[/fly]
2013-04-01 21:46
邓士林
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:淮河河畔
等 级:贵宾
威 望:61
帖 子:2392
专家分:13384
注 册:2013-3-3
收藏
得分:0 
看来我得好好学习了

Maybe
2013-04-01 22:39
xiao89
Rank: 1
等 级:新手上路
帖 子:11
专家分:9
注 册:2012-7-8
收藏
得分:0 
尼玛,要好好学习了,都没看懂
2013-04-01 22:49
sala0127
Rank: 2
等 级:论坛游民
帖 子:56
专家分:52
注 册:2011-11-8
收藏
得分:0 
回复 11楼 azzbcc
可以解释一下你的思路吗
2013-04-02 15:47
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
最原始的方法,穷举所有可能,计算出次数,统计到数组中

将9000下一步的所有可能 n入队列,并使ss[n] = ss[9000]+1。

然后出队列,假设为x,再将 x下一步所有可能 y入队列,并使 ss[y] = ss[x]+1

如果某状态ss[n]非0,说明原来出现过,不入队列


一直这样循环到队列空,就把所有可能统计到ss数组中了

再把数组中剩下的置 -1,表示不可能达到


[fly]存在即是合理[/fly]
2013-04-02 16:52
sala0127
Rank: 2
等 级:论坛游民
帖 子:56
专家分:52
注 册:2011-11-8
收藏
得分:0 
回复 15楼 azzbcc
嗯,看懂了,谢谢,穷举虽然可能慢但是好理解,从fourleaves的帖子里找到的beyondyf大神和laoyang103大神他们用的方法一时半会还看不懂,还得慢慢琢磨。。
2013-04-02 22:10
末十六沙
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2013-4-20
收藏
得分:0 
分红酒

程序代码:
#include"stdio.h"
int a[4]={9,7,4,2},c[1000][5],n=0;
fun(int b[4],int z)
{
    int i,j,k,s;
    for(i=0;i<n;i++)
    {
        if(c[i][0]==b[0]&&c[i][1]==b[1]&&c[i][2]==b[2]&&c[i][3]==b[3])
        {
            if(z<c[i][4])
                c[i][4]=z;
            else
                return;
        }
    }
    if(i==n)
    {
    c[n][0]=b[0];
    c[n][1]=b[1];
    c[n][2]=b[2];
    c[n][3]=b[3];
    c[n++][4]=z;
    }
    for(i=0;i<4;i++)//从哪里开始倒酒
    {
        if(b[i]==0)continue;
        for(j=0;j<4;j++)//可能倒到哪个瓶子里去
        {
            if(i==j||b[j]==a[j])continue;
            k=a[j]-b[j];
            if(b[i]-k<0)
                k=b[i];
            b[i]=b[i]-k;
            b[j]=b[j]+k;
            fun(b,z+1);
            b[i]=b[i]+k;
            b[j]=b[j]-k;
        }
    }
}
void main()
{
    int b[4]={9,0,0,0},i;
    fun(b,0);
    while(1)
    {
    scanf("%d,%d,%d,%d",&b[0],&b[1],&b[2],&b[3]);
    for(i=0;i<n;i++)
        if(c[i][0]==b[0]&&c[i][1]==b[1]&&c[i][2]==b[2]&&c[i][3]==b[3])
        {
            printf("%d\n",c[i][4]);
            break;
        }
    if(i==n)printf("-1\n");
//    printf("%d\n",n);
    }
}


图片附件: 游客没有浏览图片的权限,请 登录注册
收到的鲜花
  • Susake2013-04-20 13:35 送鲜花  1朵   附言:...
2013-04-20 13:26
y3765258
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:106
专家分:172
注 册:2013-4-9
收藏
得分:0 
砝码的题
绝对是循环最方便。
int a[5],b[5];  n 称的重量
a[5]={1,3,9,27,81}
for(b[0]=-1;b[0]<2;b[0]++)
for(b[1]=-1;b[1]<2;b[1]++)
for(b[2]=-1;b[2]<2;b[2]++)
for(b[3]=-1;b[3]<2;b[3]++)
for(b[4]=-1;b[4]<2;b[4]++)
{
if(b[0]*a[0]+b[1]*a[1]+b[2]*a[2]+b[3]*a[3]+b[4]*a[4]==n)
printf("%d%d%d%d%d",b[0]*a[0]+b[1]*a[1]+b[2]*a[2]+b[3]*a[3]+b[4]*a[4]);//这道题就这么简单,用循环就是这么自信哈哈。
}
第二道题  就是不定方程  明天我在看吧。

有问题一起探讨,一起进步。
2013-04-20 23:01
y3765258
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:106
专家分:172
注 册:2013-4-9
收藏
得分:0 
哦 都结出来了。大神就是多啊,我要好好学习了。

有问题一起探讨,一起进步。
2013-04-20 23:02
yctchxf
Rank: 6Rank: 6
来 自:盐城
等 级:侠之大者
威 望:2
帖 子:176
专家分:454
注 册:2012-4-10
收藏
得分:0 
来学习……
2013-04-21 00:17
快速回复:砝码称重问题和分红酒问题
数据加载中...
 
   



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

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