题目大意:中文题不说了。
题目思路:我有同学用GCD数论写出来的代码很简洁,但是很抱歉,数论蒟蒻,我觉得比赛的时候我没办法推出。如果用BFS的话思路很简单的,就是6方向广搜,只不过稍微麻烦点。具体看代码吧。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<iostream> #define MAX 115 using namespace std; int vis[MAX][MAX][MAX],a,b,c,k; bool check(int s,int n,int m) { if(!vis[s][n][m] && s<=c && n<=a && m<=b && s>=0 && n>=0 && m>=0) return true; return false; } struct node { int s,n,m,step; }; int BFS() { node now,next; now.s=c; now.n=0; now.m=0; now.step=0; queue<node>Q; Q.push(now); vis[c][0][0]=1; while(!Q.empty()) { now=Q.front(); Q.pop(); if(now.s==k && now.m==k) { return now.step; } for(int i=0;i<6;i++) { if(i==0)//s->n { if(now.s==0) continue; if(now.s >= (a-now.n)) { next.s=now.s-(a-now.n); next.n=a; } else { next.s=0; next.n=now.n+now.s; } next.m=now.m; } else if(i==1)//n->m { if(now.n==0) continue; if(now.n >= (b-now.m)) { next.n=now.n-(b-now.m); next.m=b; } else { next.n=0; next.m=now.m+now.n; } next.s=now.s; } else if(i==2)//m->n { if(now.m==0) continue; if(now.m >= (a-now.n)) { next.m=now.m-(a-now.n); next.n=a; } else { next.m=0; next.n=now.n+now.m; } next.s=now.s; } else if(i==3)//s->m { if(now.s==0) continue; if(now.s >= (b-now.m)) { next.s=now.s-(b-now.m); next.m=b; } else { next.s=0; next.m=now.m+now.s; } next.n=now.n; } else if(i==4)//n->s { if(now.n==0) continue; if(now.n >= (c-now.s)) { next.n=now.n-(c-now.s); next.s=c; } else { next.n=0; next.s=now.s+now.n; } next.m=now.m; } else if(i==5)//m->s { if(now.m==0) continue; if(now.m >= (c-now.s)) { next.m=now.m-(c-now.s); next.s=c; } else { next.m=0; next.s=now.s+now.m; } next.n=now.n; } if(check(next.s,next.n,next.m)) { vis[next.s][next.n][next.m]=1; next.step=now.step+1; Q.push(next); } } } return -1; } int main() { while(scanf("%d%d%d",&c,&a,&b),a+b+c) { if(a > b) swap(a,b); if(c%2!=0) { printf("NO\n"); continue; } else { k=c/2; memset(vis,0,sizeof(vis)); int ans=BFS(); if(ans==-1) printf("NO\n"); else printf("%d\n",ans); } } return 0; }
时间: 2024-10-24 11:10:58