题目1457:非常可乐

题目描述:

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升(正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。

输入:

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。

输出:

如果能平分的话请输出最少要倒的次数,否则输出"NO"。

样例输入:
7 4 3
4 1 3
0 0 0
样例输出:
NO
3

一看到要求最少的步数就知道用bfs了

我们用visit数组标记状态,每个状态有三个整数组成,分别表示这三个杯子里的可乐数量

然后对每个状态的递推是 6种,也就是从一个杯子倒到另外两个,再标记,入队

所以 题目还是蛮简单的

AC代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <queue>

using namespace std;

const int maxsize = 102;

int visit[maxsize][maxsize][maxsize];//标记数组

struct Node {

int x;

int y;

int z;

int step;

};//每一种可能状态

int BFS(int s, int n, int m){//广度搜索

memset(visit,0,sizeof(visit));//初始化

Node node,temp;

node.x = s;

node.y = 0;

node.z = 0;

node.step = 0;

visit[s][0][0] = 1;

queue<Node> q;

q.push(node);

while(!q.empty()){

temp = q.front();

q.pop();//出队

if((temp.x == temp.y && temp.z == 0)||(temp.x == temp.z && temp.y == 0)||(temp.y == temp.z &&
temp.x == 0)){

//判断是否达到题目要求的结果

return temp.step;

}

if(temp.x > 0){//若第一个杯子还有饮料,则有可能向另外两个杯子倒饮料

if(temp.y < n){//向第二个杯子倒

int t = n - temp.y;

if(temp.x < t){

node.x = 0;

node.y = temp.y + temp.x;

node.z = temp.z;

node.step = temp.step + 1;

}else{

node.x = temp.x - t;

node.y = n;

node.z = temp.z;

node.step = temp.step + 1;

}

if(!visit[node.x][node.y][node.z]){//若没被标记过则入队

q.push(node);

visit[node.x][node.y][node.z] = 1;

}

}

if(temp.z < m){//向第三个杯子到

int t = m - temp.z;

if(temp.x < t){

node.x = 0;

node.z = temp.z + temp.x;

node.y = temp.y;

node.step = temp.step + 1;

}else{

node.x = temp.x - t;

node.z = m;

node.y = temp.y;

node.step = temp.step + 1;

}

if(!visit[node.x][node.y][node.z]){

q.push(node);

visit[node.x][node.y][node.z] = 1;

}

}

}

if(temp.y > 0){//分析过程同上

if(temp.x < s){

int t = s - temp.x;

if(temp.y < t){

node.y = 0;

node.x = temp.x + temp.y;

node.z = temp.z;

node.step = temp.step + 1;

}else{

node.y = temp.y - t;

node.x = s;

node.z = temp.z;

node.step = temp.step + 1;

}

if(!visit[node.x][node.y][node.z]){

q.push(node);

visit[node.x][node.y][node.z] = 1;

}

}

if(temp.z < m){

int t = m - temp.z;

if(temp.y < t){

node.y = 0;

node.z = temp.z + temp.y;

node.x = temp.x;

node.step = temp.step + 1;

}else{

node.y = temp.y - t;

node.z = m;

node.x = temp.x;

node.step = temp.step + 1;

}

if(!visit[node.x][node.y][node.z]){

q.push(node);

visit[node.x][node.y][node.z] = 1;

}

}

}

if(temp.z > 0){//分析过程同上

if(temp.x < s){

int t = s - temp.x;

if(temp.z < t){

node.z = 0;

node.x = temp.x + temp.z;

node.y = temp.y;

node.step = temp.step + 1;

}else{

node.z = temp.z - t;

node.x = s;

node.y = temp.y;

node.step = temp.step + 1;

}

if(!visit[node.x][node.y][node.z]){

q.push(node);

visit[node.x][node.y][node.z] = 1;

}

}

if(temp.y < n){

int t = n - temp.y;

if(temp.z < t){

node.z = 0;

node.y = temp.y + temp.z;

node.x = temp.x;

node.step = temp.step + 1;

}else{

node.z = temp.z - t;

node.y = n;

node.x = temp.x;

node.step = temp.step + 1;

}

if(!visit[node.x][node.y][node.z]){

q.push(node);

visit[node.x][node.y][node.z] = 1;

}

}

}

}

return -1;

}

int main(){

int S,N,M;

int myStep;

while(scanf("%d %d %d",&S,&N,&M) != EOF && !(S == 0 && N == 0 && M == 0)){

if(S == 0){

myStep = -1;

}else{

myStep = BFS(S,N,M);

}

if(myStep == -1){

printf("NO\n");

}else{

printf("%d\n",myStep);

}

}

return 0;

}

时间: 2024-12-05 11:44:09

题目1457:非常可乐的相关文章

题目1457:非常可乐(广度优先遍历BFS)

题目链接:http://ac.jobdu.com/problem.php?pid=1457 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: // // 1457 非常可乐.cpp // Jobdu // // Created by PengFei_Zheng on 22/04/2017. // Copyright © 2017 PengFei_Zheng. All rights reserved. // #include <stdio

九度oj 题目1457:非常可乐

题目描述: 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升(正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) .聪明的ACMER你们说他们能平分吗?如果能请输出倒可

HDU 1495 非常可乐(数论,BFS)

非常可乐 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14153    Accepted Submission(s): 5653 Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定

hihocoder #1457 : 后缀自动机四&#183;重复旋律7

#1457 : 后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里有许多作品,但是所有的作品有一个共同特征:只用了十个音符,所有的音符都表示成0-9的数字. 现在小Hi想知道这部作品中所有不同的旋律的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0).答案有可能

BFS(倒水问题) HDU 1495 非常可乐

题目传送门 1 /* 2 BFS:倒水问题,当C是奇数时无解.一共有六种情况,只要条件符合就入队,我在当该状态vised时写了continue 3 结果找了半天才发现bug,泪流满面....(网上找份好看的题解都难啊) 4 */ 5 /************************************************ 6 Author :Running_Time 7 Created Time :2015-8-4 10:54:16 8 File Name :HDOJ_1495.cpp

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI

NBUT 1457 Sona (莫队算法)

题目大意: 求一段区间内 出现的数字的次数的三次方的和 思路分析: 这要水过去的题目真是难,各种优化. 不能用map , 要离散化之后 先处理lowerbound.优化输入... 时间卡的很紧.. 题目直接用莫队水过去. 如果你超时的话,不妨试试上面三种优化. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <map> #

转载:hdu 题目分类 (侵删)

转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029. 1032.1037.1040.1048.1056.1058.1061.1070.1076.1089.1090.1091.1092.1093. 1094.1095.1096.1097.1098.1106.1108.1157.116

HDU 搜索练习 非常可乐

非常可乐 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 51 Accepted Submission(s) : 21 Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一