关于分酒问题
有一只装满12斤酒的瓶子和三只分别装10斤、6斤和3斤酒的空瓶,如何进行三等份、四等份。如果4个瓶子分别要求装5斤、3斤、2斤、2斤,能否实现?各位大神帮帮忙看下,网上给的解题思路都是用三个瓶子的,现在是四个瓶子,要怎么用DFS或者二元一次方程求解呢?能不能给出模型参考下,不要都是代码哦
程序代码:#include <iostream>
#include <vector>
#include <queue>
#include <set>
bool bar( unsigned char a0, unsigned char a1, unsigned char a2, unsigned char a3
, unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3
, unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3 );
int main( void )
{
bar( 12,0,0,0, 12,10,6,3, 4,4,4,0 );
// 输出
// 12 0 0 0
// 2 10 0 0
// 2 4 6 0
// 2 1 6 3
// 8 1 0 3
// 11 1 0 0
// 11 0 0 1
// 1 10 0 1
// 1 4 6 1
// 1 4 4 3
// 4 4 4 0
bar( 12,0,0,0, 12,10,6,3, 3,3,3,3 );
// 输出
// 12 0 0 0
// 6 0 6 0
// 3 0 6 3
// 3 3 6 0
// 3 3 3 3
bar( 12,0,0,0, 12,10,6,3, 5,3,2,2 );
// 输出
// 无法移动
return 0;
}
struct foo
{
unsigned char a[4]; // 当前容量
static unsigned char b[4]; // 最大容量
static unsigned char c[4]; // 最终容量
foo( unsigned char a0, unsigned char a1, unsigned char a2, unsigned char a3 )
{
a[0]=a0, a[1]=a1, a[2]=a2, a[3]=a3;
}
bool operator<( const foo& other ) const
{
for( size_t i=0; i!=4; ++i )
{
if( a[i] < other.a[i] ) return true;
if( a[i] > other.a[i] ) return false;
}
return false;
}
bool move( size_t from, size_t to )
{
if( from!=to && a[from]!=0 && a[to]!=b[to] )
{
unsigned char tmp = std::min( a[from], (unsigned char)(b[to]-a[to]) );
a[from] -= tmp;
a[to] += tmp;
return true;
}
return false;
}
bool isok( void ) const
{
for( size_t i=0; i!=4; ++i )
if( a[i] != c[i] ) return false;
return true;
}
};
unsigned char foo::b[4];
unsigned char foo::c[4];
std::ostream& operator<<( std::ostream& os, const foo& f )
{
return os << (unsigned)f.a[0] << '\t' << (unsigned)f.a[1] << '\t' << (unsigned)f.a[2] << '\t' << (unsigned)f.a[3] << '\n';
}
bool bar( unsigned char a0, unsigned char a1, unsigned char a2, unsigned char a3
, unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3
, unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3 )
{
foo::b[0]=b0, foo::b[1]=b1, foo::b[2]=b2, foo::b[3]=b3;
foo::c[0]=c0, foo::c[1]=c1, foo::c[2]=c2, foo::c[3]=c3;
std::queue<std::vector<foo>> steps;
steps.push( std::vector<foo>(1,foo(a0,a1,a2,a3)) );
if( steps.back().back().isok() )
{
std::cout << "不需要移动\n" << std::endl;
return true;
}
std::set<foo> unique;
unique.insert( steps.back().back() );
while( !steps.empty() )
{
for( size_t i=0; i!=4; ++i )
{
for( size_t j=0; j!=4; ++j )
{
foo new_foo = steps.front().back();
if( new_foo.move(i,j) ) // 可移
{
if( unique.insert(new_foo).second ) // 这种状态之前未出现过
{
steps.push( steps.front() );
steps.back().push_back( new_foo );
if( new_foo.isok() ) // 符合要求
{
for( std::vector<foo>::const_iterator itor=steps.back().begin(); itor!=steps.back().end(); ++itor )
std::cout << *itor;
std::cout << std::endl;
return true;
}
}
}
}
}
steps.pop();
}
std::cout << "无法移动\n" << std::endl;
return false;
}