SDUT 2780 Pots BFS

针对两个容量分别为A和B升的容器,通过一系列操作(包括填充、倾倒和转移水),寻找达到恰好C升水所需的最短步骤。采用广度优先搜索算法实现,通过状态标记避免重复计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pots
Time Limit: 1000MS Memory Limit: 65536KB
Problem 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; 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. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Example Input

3 5 4

Example Output

6

Hint

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

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node
{
    int a, b;
    int step;
}ST;
ST s[500000], t;//s[]数组模拟队列
int map[1000][1000], head, last, n, m, k;//map[][]标记这种情况出现没出现过
void bfs(int A, int B)
{
    if(head >= last)//所有可能的情况都找不到
    {
        printf("impossible\n");
        return ;
    }
    if(A == k || B == k)//两个容器的容量谁等于第三个(k)就输出
    {
        printf("%d\n", s[head].step);
        return ;
    }
    t = s[head++];//出队列
    int i;
    for(i = 0; i < 6; i++)//下一步两个容器的容量的可能性
    {
        if(i == 0 && !map[A][m])//第一个不变,第二个装满
        {
            s[last].a = A;
            s[last].b = m;
            s[last++].step = t.step + 1;//下一步等于上一次的步数次数加一
            map[A][m] = 1;
        }
        else if(i == 1 && !map[n][B])//第二个不变,第一个装满
        {
            s[last].a = n;
            s[last].b = B;
            s[last++].step = t.step + 1;
            map[n][B] = 1;
        }
        else if(i == 2 && !map[0][B])//第二个不变,倒掉第一个
        {
            s[last].a = 0;
            s[last].b = B;
            s[last++].step = t.step + 1;
            map[0][B] = 1;
        }
        else if(i == 3 && !map[A][0])//第一个不变,倒掉第二个
        {
            s[last].a = A;
            s[last].b = 0;
            s[last++].step = t.step + 1;
            map[A][0] = 1;
        }
        else if(i == 4)//B倒入A 又分为两种情况
        {
            if(A + B > n && !map[n][A + B - n])//A满 B还剩下
            {
                s[last].a = n;
                s[last].b = A + B - n;
                s[last++].step = t.step + 1;
                map[n][A + B - n] = 1;
            }
            else if(A + B <= n && !map[A + B][0])//B没有了,全倒入A
            {
                s[last].a = A + B;
                s[last].b = 0;
                s[last++].step = t.step + 1;
                map[A + B][0] = 1;
            }
        }
        else if(i == 5)
        {
            if(A + B > m && !map[A + B - m][m])//B满,A还剩下
            {
                s[last].a = A + B - m;
                s[last].b = m;
                s[last++].step = t.step + 1;
                map[A + B - m][m] = 1;
            }
            else if(A + B <= m && !map[0][A + B])//A没有了,全倒入B
            {
                s[last].a = 0;
                s[last].b = A + B;
                s[last++].step = t.step + 1;
                map[0][A + B] = 1;
            }
        }
    }
    bfs(s[head].a, s[head].b);//继续调用队列的开头
}
int main()
{
    while(~scanf("%d %d %d", &n, &m, &k))//三个容器的体积
    {
        memset(map, 0, sizeof(map));
        head = last = 0;
        map[0][0] = 1;//最开始的情况是两个容器都是空
        s[last].a = 0;//存入数组
        s[last].step = 0;//次数0
        s[last++].b = 0;
        bfs(s[head].a, s[head].b);//调用BFS
    }
    return 0;
}
### SDUT PTA 编程题解与在线评测系统使用说明 #### 关于SDUT PTA在线评测系统的概述 SDUT PTA(Programming Teaching Assistant)是一个面向学生学习编程的在线评测平台,主要用于支持山东理工大学计算机科学及相关专业的课程教学。该平台提供了丰富的练习题目以及自动化的测试机制,帮助学生巩固所学的知识并提升实际编程能力[^1]。 #### 如何使用SDUT PTA在线评测系统? 以下是关于如何有效利用SDUT PTA进行编程训练的关键要点: 1. **注册账号** 学生需通过学校指定的方式完成账户注册,并登录到对应的班级页面参与作业提交和考试活动。 2. **熟悉界面布局** 登录后可以看到左侧导航栏包含了“我的作业”、“公开试题”等功能模块;右侧则显示具体任务列表及其状态信息(未做/已交/得分情况)。点击某道题目可以查看其详细描述、样例输入输出以及其他提示内容[^2]。 3. **编写代码并调试** 对于像“计算1到n的和”的简单问题,可以直接采用如下C语言实现方式来解决: ```c #include<stdio.h> int main(){ int n, sum=0; scanf("%d",&n); for(int i=1;i<=n;i++) { sum +=i; } printf("%d\n",sum); return 0; } ``` 此段代码实现了基本的功能需求——读取用户输入的一个正整数值`n`,并通过循环累加得到最终的结果输出。 4. **提交解决方案** 完成本地开发环境中的编码工作之后,在网页端找到对应位置上传源文件或者直接粘贴文本框内的代码片段即可发起评测请求。注意遵循每道题目的特殊约束条件比如时间复杂度限制等规定。 5. **分析反馈结果** 提交完成后会迅速获得运行状况报告,如果存在错误,则应仔细阅读报错消息重新审视自己的逻辑是否存在漏洞再尝试修正直至完全正确为止。 #### 常见问题解答 对于初学者来说可能会遇到一些困惑之处,下面列举几个典型场景供参考: - 如果发现即使按照标准答案复制也得不到满分怎么办?可能是因为忽略了某些边界情形处理或者是格式化方面的小失误所致。 - 当面对较复杂的算法类挑战不知道从哪里下手时建议先梳理清楚思路画流程图辅助理解后再动手实践。 - 还有就是保持耐心多试几次不要轻易放弃因为每一次失败都是成长的机会! ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值