http://ac.jobdu.com/problem.php?pid=1147
好像 九度的oj judge 有问题,不对的code也可以过。
建议使用 UVa的测试
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=512
自己写了bfs过了,但是时间复杂度高,后来发现了 数论解决更好
参考了 http://www.cnblogs.com/kedebug/archive/2012/12/05/2802927.html
bfs code
#include <stdio.h>
#include <queue>
#include <stack>
typedef struct trace{
int pre_a, pre_b;
int action; //1: fill A, 2:fill B,
//3: pour A->B, 4:pour B->A,
//5: empty A, 6:empty B
bool visited;
} Trace;
typedef struct status{
int x,y;
}Sta;
void print_action(int a){
switch(a){
case 1:
printf("fill A\n");
break;
case 2:
printf("fill B\n");
break;
case 3:
printf("pour A B\n");
break;
case 4:
printf("pour B A\n");
break;
case 5:
printf("empty A\n");
break;
case 6:
printf("empty B\n");
break;
}
}
static Trace map[1001][1001];
int main(){
Sta st,temp;
int Ca,Cb,n;
std::queue<Sta> q;
std::stack<int> actions;
while(scanf("%d%d%d",&Ca,&Cb,&n)!=EOF ){
if(n == 0){
printf("success\n");
continue;
}
while(!q.empty()) q.pop();
while(!actions.empty()) actions.pop();
for (int i = 0; i <=Cb ; ++i) {
for (int j = 0; j<=Cb; j++) {
map[i][j].pre_a = map[i][j].pre_b = -1;
map[i][j].visited = false;
}
}
map[0][0].visited = true;
st.x = 0,st.y=0;
q.push(st);
while(!q.empty()){
st = q.front();q.pop();
if(st.x ==n || st.y == n) break;
//1.Fill A
temp.x =Ca; temp.y=st.y;
if(!map[temp.x][temp.y].visited){
map[temp.x][temp.y].visited = true;
map[temp.x][temp.y].pre_a = st.x;
map[temp.x][temp.y].pre_b = st.y;
map[temp.x][temp.y].action = 1;
q.push(temp);
}
//2.Fill B
temp.x =st.x; temp.y=Cb;
if(!map[temp.x][temp.y].visited){
map[temp.x][temp.y].visited = true;
map[temp.x][temp.y].pre_a = st.x;
map[temp.x][temp.y].pre_b = st.y;
map[temp.x][temp.y].action = 2;
q.push(temp);
}
//3.Pour A -> B
temp.x =st.x; temp.y=st.y;
while(temp.x>0 && temp.y <Cb){temp.x--; temp.y++;}
if(!map[temp.x][temp.y].visited){
map[temp.x][temp.y].visited = true;
map[temp.x][temp.y].pre_a = st.x;
map[temp.x][temp.y].pre_b = st.y;
map[temp.x][temp.y].action = 3;
q.push(temp);
}
//4.Pour B -> A
temp.x =st.x; temp.y=st.y;
while(temp.x<Ca && temp.y >0){temp.x++; temp.y--;}
if(!map[temp.x][temp.y].visited){
map[temp.x][temp.y].visited = true;
map[temp.x][temp.y].pre_a = st.x;
map[temp.x][temp.y].pre_b = st.y;
map[temp.x][temp.y].action = 4;
q.push(temp);
}
//5.Empty A
temp.x =0; temp.y=st.y;
if(!map[temp.x][temp.y].visited){
map[temp.x][temp.y].visited = true;
map[temp.x][temp.y].pre_a = st.x;
map[temp.x][temp.y].pre_b = st.y;
map[temp.x][temp.y].action = 5;
q.push(temp);
}
//6.Empty B
temp.x =st.x; temp.y=0;
if(!map[temp.x][temp.y].visited){
map[temp.x][temp.y].visited = true;
map[temp.x][temp.y].pre_a = st.x;
map[temp.x][temp.y].pre_b = st.y;
map[temp.x][temp.y].action = 6;
q.push(temp);
}
}
while(st.x!=-1 && st.y!=-1){
actions.push(map[st.x][st.y].action);
temp.x = map[st.x][st.y].pre_a;
temp.y = map[st.x][st.y].pre_b;
st.x = temp.x; st.y = temp.y;
}
while(!actions.empty()){
print_action(actions.top());
actions.pop();
}
if(!q.empty()) printf("success\n");
}
}
数论法;
code from 参考
#include <cstdio>
#include <cstdlib>
#include <cstring>
int main()
{
int ca, cb, n;
while (scanf("%d %d %d", &ca, &cb, &n) != EOF)
{
int a = 0, b = 0;
while (true)
{
if (b == n)
{
printf("success\n");
break;
}
else if (b == cb)
{
printf("empty B\n");
b = 0;
}
else if (a == 0)
{
printf("fill A\n");
a = ca;
}
else if (a != 0)
{
printf("pour A B\n");
if (a + b <= cb)
b += a, a = 0;
else
a = a + b - cb, b = cb;
}
}
}
return 0;
}