USACO Training Section1.4 Mother's Milk

状态空间是ABC三个不大于20的整数,很小。状态转换条件也很清楚,作广度优先遍历即可。关键依然是如何记录状态。与clocks的方法类似,使用单个整数来记录状态,使用位操作来做基本操作。

事实上可以只记录两个筒的状态而不是三个,因为牛奶的总数是已知的。不过这样使得编程复杂度上升。

原题链接
[url]http://ace.delos.com/usacoprob2?a=sagomFwQFqE&S=milk3[/url]


/*
ID: blackco3
TASK: milk3
LANG: C++
*/
#include <fstream>
#include <memory.h>

#define _max_state_ 1<<15
#define _max_cap_ 32
using namespace std;
int cap[3];
int visited[_max_state_], queue[_max_state_] ;

inline int trans( int org, int from, int to )
{
int tmp[3]={ org&0x1f, (org>>5)&0x1f, (org>>10)&0x1f };
if( tmp[from]==0 || tmp[to]==cap[to] )
return org ;
if( tmp[from]>cap[to]-tmp[to] )
tmp[from] -= cap[to]-tmp[to], tmp[to]=cap[to] ;
else
tmp[to] += tmp[from], tmp[from]=0 ;
return tmp[0] | (tmp[1]<<5) | (tmp[2]<<10) ;
}

int main()
{
int base ;
ifstream fin("milk3.in");
fin >> cap[0] >> cap[1] >> cap[2] ;

int c_remain[_max_cap_];
memset(c_remain, 0, sizeof(c_remain) );
int *head=queue, *tail=queue ;
*(tail++)=(cap[2]<<10), visited[*head]=1, c_remain[cap[2]]=1 ;
register int nstate ;
do{
for( int from=0; from<3; from++ ){
for( int to=0; to<3; to++){
if(from==to)
continue ;
nstate=trans(*head, from, to);
if( visited[nstate] )
continue ;
visited[nstate]=1 ;
*(tail++)=nstate ;
if( !(nstate&0x1f) ){
c_remain[ (nstate>>10)&0x1f ]=1 ;
}
}
}
}while((++head)!=tail);

ofstream fout("milk3.out");
for(int i=0, first=1 ; i<=cap[2]; i++){
if( c_remain[i] ){
if( !first )
fout << " ";
fout << i ;
first=0 ;
}
}
fout << endl ;
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值