uva 1631

1631 Locker

A password locker with N digits, each digit can be rotated to 0-9 circularly.

You can rotate 1-3 consecutive digits up or down in one step.

For examples:

567890 → 567901 (by rotating the last 3 digits up)

000000 → 000900 (by rotating the 4th digit down)

Given the current state and the secret password, what is the minimum amount of steps you have to rotate the locker in order to get from current state to the secret password?

Input

Multiple (less than 50) cases, process to EOF.

For each case, two strings with equal length (≤ 1000) consists of only digits are given, representing the current state and the secret password, respectively.

Output

For each case, output one integer, the minimum amount of steps from the current state to the secret password.

Sample Input

111111 222222

896521 183995

Sample Output

2

12

记忆化搜索

从第一个开始,枚举向上或向下转1个,2个,3个的情况,然后记忆化搜索,注意最后一个字符在处理时要使第n + 1,n + 2个的初始和末状态相同。

#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define INF 100000
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
#define repu(i, a, b) for(int i = a; i < b; i++)
#define MAXN 1005
char sa[MAXN], sb[MAXN];
int a[MAXN], b[MAXN];
int d[MAXN][10][10];
int n;

int up(int s, int t)
{
    if(s <= t) return t - s;
    return (10 + t - s);
}

int down(int s, int t)
{
    if(s >= t) return s - t;
    return (10 + s - t);
}

int dp(int d1, int d2, int d3)
{
    if(d1 >= n) return 0;
    if(d[d1][d2][d3] != -1) return d[d1][d2][d3];
    int t, minn = INF;
    t = up(d2, b[d1]);
    repu(i, 0, t + 1)
      repu(j, i, t + 1)
       minn = min(minn, dp(d1 + 1, (d3 + j) % 10, (a[d1 + 2] + i) % 10) + t);
    t = down(d2, b[d1]);
    repu(i, 0, t + 1)
      repu(j, i, t + 1)
       minn = min(minn, dp(d1 + 1, (d3 - j + 10) % 10, (a[d1 + 2] - i + 10) % 10) + t);
    return d[d1][d2][d3] = minn;
}

int main()
{
    while(~scanf("%s%s", sa, sb))
    {
        n = strlen(sa);
        repu(i, 0, n) a[i] = sa[i] - ‘0‘;
        repu(i, 0, n) b[i] = sb[i] - ‘0‘;
        a[n] = a[n + 1] = b[n] = b[n + 1] = 0;

        _cle(d, -1);
        printf("%d\n", dp(0, a[0], a[1]));
    }
    return 0;
}

时间: 2024-12-07 21:36:24

uva 1631的相关文章

HDU 4433 locker(DP)( UVA 1631 - Locker)

题目链接:点击打开链接 题意:有一个n位密码锁,每一位都是0~9,可以循环旋转,每次可以让1~3个相邻数字同时往上或者往下旋转一格. 输入初始状态和终止状态,问最少需要转几次. 思路: 很显然是个DP题目, 由于每次可以让相邻的1~3个数字同时旋转, 所以状态的表示上就要考虑相邻3个位置. 那么可以用d[i][a][b][c]表示当前到了第i位,第i位上当前是a,i+1位是b,i+2位是c. 那么显然必须让i位上变成目标数字了, 因为接下来就转移到i+1位了,说明前i位已经全部转到目标态了.  

UVa 1631 Locker (DP)

题意:有一个 n 位密码锁,每位都是0-9,可以循环旋转.同时可以让1-3个相邻数字进行旋转一个,给定初始状态和目状态,问你最少要转多少次. 析:很明显的一个DP题.dp[i][j][k] 表示前 i 位已经转好,并且第 i+1 位是 j ,第 i+2 位是 k,那么我们先把第 i 位转到指定位置,然后计算转多少次, 然后再考虑 i+1位和 i+2位,要旋转小于等于第 i 位的次数,这就转移完了.比较简单的一个DP,只是没有遇见过. 代码如下: #pragma comment(linker, "

UVa1631

题意: 有一个n(n≤1000)位密码锁,每位都是0-9,可以循环旋转.每次让1-3个相邻数字同时往上或者往下转一格,567890->567901(最后3位向上).输入初始状态和终止状态(长度不超过1000),问最少要转几次. 这道题刚开始看有点蒙,不知道应该如何转密码锁上面的格,然后通过经验能够感觉出来最优的转动方案是可以按照 从左到右的顺序来移动到正确的位置的,这样我们将无序的转动变成了有序的转动,自然问题就简化了许多, 然后通过观察题意(每次让1-3个相邻数字同时往上或者往下转一格),我发

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

[UVa] Palindromes(401)

UVA - 401 Palindromes Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDED

uva 401.Palindromes

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=342 题目意思:给出一段字符串(大写字母+数字组成).判断是否为回文串 or 镜像串 or 回文镜像串 or 什么都不是.每个字母的镜像表格如下 Character Reverse Character Reverse Character Reverse A A M M Y Y B

[2016-02-19][UVA][129][Krypton Factor]

UVA - 129 Krypton Factor Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description You have been employed by the organisers of a Super Krypton Factor Contest in which contestants have very high mental and physica