HDU-1495 非常可乐 (嵌套结构体-广搜 对比 一般广搜)
题意
Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。Output如果能平分的话请输出最少要倒的次数,否则输出"NO"。Sample Input
- 7 4 3
- 4 1 3
- 0 0 0
Sample Output
- NO
- 3
- ---------------------------------------------------------我是分割线----------------------------------------------------------------------------------------------------------------------
- 某童靴的一般思路 (感谢@陌类 提供的代码)
(较麻烦的题解, 好像多数人都这么写~
- #include <stdio.h>
- #include <string.h>
- #include <algorithm>
- #include <queue>
- #define N 110
- using namespace std;
- int vis[N][N][N];
- int s,n,m;
- struct node
- {
- int n,s,m,step;
- };
- int cheak(int x,int y,int z)
- {
- if(x==&&y==z)
- return ;
- if(y==&&x==z)
- return ;
- if(z==&&x==y)
- return ;
- return ;
- }
- int bfs()
- {
- queue<node>Q;
- node now,next;
- now.s=s;
- now.n=;
- now.m=;
- now.step=;
- vis[s][][]=;
- Q.push(now);
- while(Q.size())
- {
- now=Q.front();
- Q.pop();
- if(cheak(now.s,now.n,now.m))//检查状态
- {
- return now.step;
- }
- for(int i=;i<=;i++)
- {
- if(now.s!=)
- {
- if(i==&&now.n!=n)
- {
- if(now.n+now.s>n)
- {
- next.n=n;
- next.s=now.s-(n-now.n);
- }
- else
- {
- next.n=now.n+now.s;
- next.s=;
- }
- next.m=now.m;
- next.step=now.step+;
- if(!vis[next.s][next.n][next.m])
- {
- vis[next.s][next.n][next.m]=;
- Q.push(next);
- }
- }
- else if(i==&&now.s!=&&now.m!=m)
- {
- if(now.m+now.s>m)
- {
- next.m=m;
- next.s=now.s-(m-now.m);
- }
- else
- {
- next.m=now.m+now.s;
- next.s=;
- }
- next.n=now.n;
- next.step=now.step+;
- if(!vis[next.s][next.n][next.m])
- {
- vis[next.s][next.n][next.m]=;
- Q.push(next);
- }
- }
- }
- if(now.n!=)
- {
- if(i==&&now.m!=m)
- {
- if(now.m+now.n>m)
- {
- next.m=m;
- next.n=now.n-(m-now.m);
- }
- else
- {
- next.m=now.m+now.n;
- next.n=;
- }
- next.s=now.s;
- next.step=now.step+;
- if(!vis[next.s][next.n][next.m])
- {
- vis[next.s][next.n][next.m]=;
- Q.push(next);
- }
- }
- else if(i==&&now.n!=&&now.s!=s)
- {
- if(now.m+now.s>s)
- {
- next.s=s;
- next.n=now.n-(s-now.s);
- }
- else
- {
- next.s=now.n+now.s;
- next.n=;
- }
- next.m=now.m;
- next.step=now.step+;
- if(!vis[next.s][next.n][next.m])
- {
- vis[next.s][next.n][next.m]=;
- Q.push(next);
- }
- }
- }
- if(now.m!=)
- {
- if(i==&&now.m!=&&now.n!=n)
- {
- if(now.n+now.m>n)
- {
- next.n=n;
- next.m=now.m-(n-now.n);
- }
- else
- {
- next.n=now.n+now.m;
- next.m=;
- }
- next.s=now.s;
- next.step=now.step+;
- if(!vis[next.s][next.n][next.m])
- {
- vis[next.s][next.n][next.m]=;
- Q.push(next);
- }
- }
- else if(i==&&now.m!=&&now.s!=s)
- {
- if(now.s+now.m>s)
- {
- next.s=s;
- next.m=now.m-(s-now.s);
- }
- else
- {
- next.s=now.s+now.m;
- next.m=;
- }
- next.n=now.n;
- next.step=now.step+;
- if(!vis[next.s][next.n][next.m])
- {
- vis[next.s][next.n][next.m]=;
- Q.push(next);
- }
- }
- }
- }
- }
- return -;
- }
- int main()
- {
- while(scanf("%d%d%d",&s,&n,&m),s+n+m!=)
- {
- if(s%!=)
- {
- printf("NO\n");
- }
- else
- {
- memset(vis,,sizeof(vis));
- int ans;
- ans=bfs();
- if(ans>=)
- printf("%d\n",ans);
- else
- printf("NO\n");
- }
- }
- return ;
- }
简单点评
在上面的代码, 每次for循环都将枚举六种情况 ,1->2 , 1-》3,2-》3 ,2-》1,3-》1,3-》2 ,并且每种情况又要分为两种来讨论......
重复的部分太多了~
重复的部分太多了~
不够简洁,代码太长长了。
出错误了一不好找啊!
-------------------------------------------------------------------------------------------------------------------------------------我是分割线---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
起先我也是这么做的,后来我想了一个相对简单的优化办法:
进行结构体的嵌套 ,结构体cup 的 a[1]/a[2]/a[3]分别代表这 三个容器 ,其中结构体 cup中 up 代表一个容器的装水上限 ,now 代表现在的水量! 再用 结构体node 将cup和step 封装起来!
- #include<iostream>
- #include<algorithm>
- #include<cstdio>
- #include<cstring> //by @山枫叶纷飞
- #include<cstdlib>
- #include<cmath>
- #include<string>
- #include<set>
- #include<queue>
- using namespace std;
- typedef long long ll;
- double dinf=99999999.9, mm=1e-;
- const int N=,inf=0x3f3f3f3f;
- int s,n,m;
- int vis[N][N][N];
- struct cup
- {
- int up,now;
- };
- struct node
- {
- cup a[]; ///进行结构体的嵌套 ,a[1]/a[2]/a[3] 分别表示三个容器
- int step;
- };
- int bfs( )
- {
- int i,j,k;
- queue<node>Q;
- node p,q;
- p.a[].now=s;p.a[].up=s;
- p.a[].now=;p.a[].up=n;
- p.a[].now=;p.a[].up=m;
- p.step=;
- memset(vis,,sizeof(vis));vis[s][][]=;
- Q.push(p);
- while(Q.size()>)
- {
- p=Q.front(); ///从队列中取到的现在的状态
- Q.pop();
- if((p.a[].now==s/&&p.a[].now==s/) || (p.a[].now==s/&&p.a[].now==s/))///判断是否达到预期结果
- return p.step;
- if((p.a[].now==s/&&p.a[].now==s/))///判断是否达到预期结果(太长了,拆成了两段)
- return p.step;
- for(i=;i<=;i++)
- {
- for(j=;j<=;j++)
- {
- if(i==j || p.a[i].now==||p.a[j].now==p.a[j].up)///简易排除
- continue;
- q=p;///初始化,q 代表由p 延伸来的下一状态
- int dif=p.a[j].up-p.a[j].now;///表示容器a[j]最多可添加水量
- if(p.a[i].now>=dif)///若容器a[j]可被填满水
- {
- q.a[i].now=p.a[i].now-dif;
- q.a[j].now=p.a[j].up;
- }
- else ///若容器a[j]不能装满水
- {
- q.a[i].now=;
- q.a[j].now=p.a[i].now+p.a[j].now;
- }
- q.step=p.step+;
- if(vis[q.a[].now][q.a[].now][q.a[].now]==)
- {
- vis[q.a[].now][q.a[].now][q.a[].now]=;
- Q.push(q);
- }
- }
- }
- }
- return -;
- }
- int main()
- {
- while(scanf("%d%d%d",&s,&n,&m),s+n+m)
- {
- if(s%!=)///奇数一定无法均分成两份
- printf("NO\n");
- else
- {
- int k=bfs();
- if(k==-)
- printf("NO\n");
- else
- printf("%d\n",k);
- }
- }
- return ;
- }
简单点评
两重for 循环,用a[i] 和a[j] 来模拟全部六种情况的倒水过程 ,省了超过100行的代码, 结构体的含义一目了然, 就是结构体名字写起来太长了!
还有要注意的是: { q=p;///初始化,q 代表由p 延伸来的下一状态}这段代码的位置很重要, 每次新的内层for循环都要记得将q重新初始化, 不然会造成意料之外的错误! 当时debug 到了 "debug人在天涯"!
- ---------------------------------------------------------我是分割线----------------------------------------------------------------------------------------------------------------------
其他思路
这个题目用数论也是可以做的! 近似玄学,,,感兴趣的话自行百度!
HDU-1495 非常可乐 (嵌套结构体-广搜 对比 一般广搜)的更多相关文章
- HDU 1495 非常可乐 (只是转了个弯的广搜题)
N - 非常可乐 =========================================================================================== ...
- abap中结构体嵌套结构体。
1: 结构体中嵌套结构体. *&---------------------------------------------------------------------* *& Re ...
- C语言 结构体(嵌套结构体--结构体数组)
//结构体--嵌套结构体和结构体数组 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> ...
- BFS(倒水问题) HDU 1495 非常可乐
题目传送门 /* BFS:倒水问题,当C是奇数时无解.一共有六种情况,只要条件符合就入队,我在当该状态vised时写了continue 结果找了半天才发现bug,泪流满面....(网上找份好看的题解都 ...
- matlab学习笔记12_2创建结构体数组,访问标量结构体,访问非标量结构体数组的属性,访问嵌套结构体中的数据,访问非标量结构体数组中多个元素的字段
一起来学matlab-matlab学习笔记12 12_2 结构体 创建结构体数组,访问标量结构体,访问非标量结构体数组的属性,访问嵌套结构体中的数据,访问非标量结构体数组中多个元素的字段 觉得有用的话 ...
- go变量、类的概念以及类的使用方式,嵌套结构体
go变量.类的概念以及类的使用方式,嵌套结构体 Go变量 go使用var声明变量,当声明变量时,这个变量对应的值总是会被初始化.这个值要么用指定的值初始化,要么用零值(即变 量类型的默认值)做初始化. ...
- hdu 1495 非常可乐 (广搜)
题目链接 Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶 ...
- hdu 1495 非常可乐 广搜
#include<iostream> #include<cstdio> #include<cstring> #include<queue> ][][]; ...
- HDU 1495 非常可乐(数论,BFS)
非常可乐 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
随机推荐
- Spring 3整合Quartz 2实现手动设置定时任务:新增,修改,删除,暂停和恢复(附带源码)
摘要:在项目的管理功能中,对定时任务的管理有时会很常见.但一般定时任务配置都在xml中完成,包括cronExpression表达式,十分的方便.但是如果我的任务信息是保存在数据库的,想要动态的初始化, ...
- 正则表达式去除字符串左右空格函数 调用方法是,str.Trim();
正则表达式去除字符串左右空格函数 调用方法是,str.Trim(); String.prototype.Trim = function() { return this.replace(/(^\s*)| ...
- Ubuntu下使用nginx和nginx-rtmp-module搭建流媒体服务器的正确姿势
之前在使用nginx和nginx-rtmp-module搭建流媒体服务器的时候遇到一个很尴尬的问题,就是在把nginx-rtmp-module模块添加到nginx中去的时候,我最开始采取的做法是先卸载 ...
- undefined variable _session php
解决方法: if (version_compare(PHP_VERSION, '5.4.0', '<')) { if(session_id() == '') {session_start();} ...
- smarty模板基础知识
1.定义 Smarty是一个使用php写出来的模板引擎,它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与html代码混杂在一起PHP代码逻辑分离. 简单的讲,目的就是要使PH ...
- MATLAB命令大全和矩阵操作大全
转载自: http://blog.csdn.net/dengjianqiang2011/article/details/8753807 MATLAB矩阵操作大全 一.矩阵的表示在MATLAB中创建矩阵 ...
- work1-英语辅导班在线报名系统
作品简述: 这是一个英语辅导班在线报名系统,目的是提供一个供学生报名辅导班的平台,也同时为老师收集报名信息提供便利. 使用的语言: php+html+js 服务器: 新浪sae服务器,apache 数 ...
- Error detected while processing function CheckFoam256 问题的解决
今天在打开OpenFOAM的constant文件的时候, vim-OpenFOAM-syntax插件遇到了如下问题: Error detected while processing function ...
- PHP xmapp 下面安装 Composer-Setup.exe
1.打开PHP配置文件E:\xampp\php\php.ini确认以下模块已开启(移除前面的分号). extension=php_openssl.dll, (php.ini文档里面开启一次就OK了) ...
- Angular基础(一)
AngularJS有五个主要核心特性,如下介绍: 双向数据绑定 -- 实现了把model与view完全绑定在一起,model变化,view也变化,反之亦然. 模板 -- 在AngularJS中,模板相 ...