[ZOJ 2961] Spinlock [搜索]

来源:互联网 发布:鼎信诺审计软件多少钱 编辑:程序博客网 时间:2024/06/06 03:35

已知一个密码锁,最多有6位数字,每个数字都是10进制数。有100个按钮,每个按钮可以让某些数字转动若干次。你只能通过按按钮来转动密码锁。问最小的按按钮的次数,输出字典序最小的序列。

搜索,BFS即可。把每个状态当成一个点,复杂度略微有点高..最坏有10^8条边...但是好像不会到这么坏...

#include <cstdio>#include <algorithm>using namespace std;const int INF=~0u>>1;int minv[1000000];int from[1000000];int que[1000000];int ans[1000000];int a[100];int pow[7];int d,n,s,t,p,q,m;inline int calTo(int i,int j) {int ans=0,k;for (k=0;k<d;k++) {ans+=(i+j)%10*pow[k];i/=10;j/=10;}return ans;}inline int cal(int i,int j) {int ans=0,k;for (k=0;k<d;k++) {ans+=(j-i+2000000)%10*pow[k];i/=10;j/=10;}return ans;}inline void print(int x) {for (int k=d-1;k>=0;k--) {printf("%d",x/pow[k]%10);}printf("\n");}int main() {int i,j,k;pow[0]=1;for (i=0;i<6;i++) pow[i+1]=pow[i]*10;while (scanf("%d%d",&d,&n)!=EOF) {for (i=0;i<n;i++) scanf("%d",&a[i]);sort(a,a+n);m=pow[d];scanf("%d%d",&s,&t);for (i=0;i<m;i++) minv[i]=INF;p=q=0;que[q++]=s;minv[s]=0;while (p!=q&&que[p]!=t) {i=que[p++];//printf("from %d\n",i);for (j=0;j<n;j++) {k=calTo(i,a[j]);//printf(" add %d = %d\n",a[j],k);if (minv[k]==INF) {minv[k]=minv[i]+1;from[k]=i;que[q++]=k;}}}if (minv[t]==INF) printf("-1\n");else {p=0;q=t;while (q!=s) {//printf("-- %d + %d -> %d\n",from[q],cal(from[q],q),q);ans[p++]=cal(from[q],q);q=from[q];}printf("%d\n",p);while (p--) {print(ans[p]);}}}return 0;}


0 0
原创粉丝点击