题意翻译
有一个n(n≤1000)位密码锁,每位都是0~9,可以循环旋转。每次让1~3个相邻数字同时往上或者往下转一格,567890->567901(最后3位向上)。输入初始状态和终止状态(长度不超过1000),问最少要转几次。
题目描述
输入输出格式
输入格式:
输出格式:
输入输出样例
暂无测试点
dp[i][j][k][l] 表示到第i个,第i个数为j,i+1的数为k,i+2的数为l
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e3+10; int kase=0,vis[maxn][10][10][10],f[maxn][10][10][10],n; int a[maxn],b[maxn]; char aa[maxn],bb[maxn]; int dp(int cur,int x,int y,int z) { if(cur>=n) return 0; int& ans = f[cur][x][y][z]; if(vis[cur][x][y][z]==kase) return ans; vis[cur][x][y][z]=kase; ans=inf; int t; if(x<=b[cur]) t=b[cur]-x; else t=b[cur]+10-x; for(int i=0;i<=t;i++) for(int j=0;j<=i;j++) ans=min(ans,dp(cur+1,(y+i)%10,(z+j)%10,a[cur+3])+t); if(x>=b[cur]) t=x-b[cur]; else t=x+10-b[cur]; for(int i=0;i<=t;i++) for(int j=0;j<=i;j++) ans=min(ans,dp(cur+1,(y-i+10)%10,(z-j+10)%10,a[cur+3])+t); return ans; } int main() { //freopen("in.txt","r",stdin); while(scanf("%s%s",&aa,&bb)!=EOF) { ++kase; n=strlen(aa); for(int i=0;i<n;i++) a[i]=aa[i]-'0',b[i]=bb[i]-'0'; a[n] = a[n + 1] = b[n] = b[n + 1] = 0; printf("%d ",dp(0,a[0],a[1],a[2])); } return 0; }