ACM/ICPC HDU 1195

本年度还有8篇博客需要完成
开篇前附加一个看完《盗梦空间》的我的假设
这假设和薛定谔的猫处于半死半活的叠加态感觉有点像


世界全都是我做的梦
1:因为世界中的任何一个人“你”,不能对我证明“你”是有意识的还是只是我的虚构。
2:“你”是有意识还是虚构只能由你自己证明


这是我的某一篇论坛回复
原题是hdu的1195;题目是英文的,大意我翻译一下。

有一个紧急开启密码锁的任务。密码由四位数字组成;每个数字从1到9;每次,可以对每一个数字进行加1或者减1;当从1加到9时,由9再加1会变为1;当从9减到1时,由1再减1会变为9;也可以交换两个相邻的数字,每次操作作为一个step

你的任务就是用最少的步骤解锁
附加:最左边的数字与最右边的数字不相邻
示例输入

1234 2144
1111 9999

示例输出
2
4



分析
首先考虑1234的下一step有可能是什么样的数字
针对每一位数字有四种操作,+1,-1,左交换,右交换(最左边的数字只有右交换,最右边只有左交换)
那么下一step的数字
第一数字位:2234,9234,2134
第二数字位:1334,1134,2134,1324
第三数字位:1244,1224,1324,1243
第四数字位:1235,1233,1243

得到下一step的所有数字,是一个明显的BFS过程。

得到最少的步数,是一个明显的DP过程。也就是STEP(n)=STEP(n-1)+1
STEP(1)=0,题中的STEP(1)就是源数字。
由此需要建立一个长度为10000的数字数组。储存从1111~9999所需要的最小步数

综上所述,代码如下




import java.util.Scanner;

public class Main {

public int openLock(int source, int target) {

int[] minumSteps = new int[10000];
boolean[] visibility = new boolean[10000];

int[] queue = new int[10000];
int index = 0;
queue[0] = source;
visibility[source] = true;
int size = 1;
while (queue[index] != 0) {
int temp = queue[index];
int[] tempAry = getAryFromInt(temp);
index++;

for (int i = 0; i < tempAry.length; i++) {
int[] steps = getNextStep(temp, i);
for (int j = 0; j < steps.length; j++) {
if (!visibility[steps[j]]) {
visibility[steps[j]] = true;
minumSteps[steps[j]] = minumSteps[temp] + 1;
queue[size++] = steps[j];
}
}
}
}
return minumSteps[target];
}

public int[] getNextStep(int ary, int index) {
int[] result = new int[4];
int i = 0;
result[i++] = add(ary, index);
result[i++] = minus(ary, index);
result[i++] = exchangeRight(ary, index);
result[i++] = exchangeLeft(ary, index);
return result;
}

public int getIntFromAry(int[] ary) {
return ary[0] * 1000 + ary[1] * 100 + ary[2] * 10 + ary[3];
}

public int[] getAryFromInt(int num) {
int[] result = new int[4];
result[0] = num / 1000;
result[1] = (num % 1000) / 100;
result[2] = (num % 100) / 10;
result[3] = num % 10;
return result;
}

public int add(int ary, int index) {
int[] result = getAryFromInt(ary);
if (result[index] == 9) {
result[index] = 1;
} else {
result[index] = result[index] + 1;
}
return getIntFromAry(result);
}

public int minus(int ary, int index) {
int[] result = getAryFromInt(ary);
if (result[index] == 1) {
result[index] = 9;
} else {
result[index] = result[index] - 1;
}
return getIntFromAry(result);
}

public int exchangeRight(int ary, int index) {
int[] result = getAryFromInt(ary);
if (index == 3) {
return getIntFromAry(result);
}
int temp = result[index];
result[index] = result[index + 1];
result[index + 1] = temp;
return getIntFromAry(result);
}

public int exchangeLeft(int ary, int index) {
int[] result = getAryFromInt(ary);
if (index == 0) {
return getIntFromAry(result);
}
int temp = result[index];
result[index] = result[index - 1];
result[index - 1] = temp;
return getIntFromAry(result);
}

public static void main(String[] args) {

Main lock = new Main();
Scanner cin = new Scanner(System.in);

int length = cin.nextInt();
int[][] keyvalue = new int[length][2];
for (int i = 0; i < length; i++) {
int key = cin.nextInt();
int value = cin.nextInt();
keyvalue[i] = new int[] { key, value };
}
for (int i = 0; i < keyvalue.length; i++) {
int step = lock.openLock(keyvalue[i][0], keyvalue[i][1]);
System.out.println(step);
}
}

}


翻了翻Accepted列表,到目前为止我是唯一一个用java语言Accepted的。。。。。深囧
附图,脑残G++编译错误的也截了
[img]http://dl.iteye.com/upload/attachment/298276/8e514a9f-daeb-3603-8203-d1be92d0acee.jpg[/img]

你可能感兴趣的:(数据结构与算法)