5-28 虫蚀算式问题
问题描述
虫蚀算式是指古书中算式的一部分被虫蛀了。虫蚀算式问题是根据虫蚀算式剩下的数字,逻辑推断被虫蛀了的数字。例如,
43?98650?45+8468?66334444550697843?98650?45+8468?663344445506978
其中“?”表示虫蛀的数字。根据此虫蚀算式,容易推断出,第 1 行的 2 个虫蛀数字分 别是 5 和 3,第 2 行的虫蛀数字是 5。
一般情况下,虫蚀算式问题假设,算式中所有数字都被虫蛀了,但是知道虫蚀算式中哪 些数字相同。另外还知道虫蚀算式是 n 进制加法算式。虫蚀算式中的 3 个数都是 n 位数,且允许前导 0。
对于给定的虫蚀算式,编程计算算式中的虫蚀数字。
数据输入:
第 1 行有 1 个正整数 n(n<=26),表示所给的虫蚀算式是 n 进制加法算式。其后 3 行中,每行有 1 个由 n 个大写英文字母组成的字 符串,分别表示虫蚀算式中的 2 个加数及其和。相同的英文字母代表相同的数字。
Java
package Chapter5HuiSuFa;
import java.util.Scanner;
public class ChongShiSuanShi {
private static class Node{
int a,b,c;
Node next;
}
private static int n;
private static int[][] B;
private static int[] x;
private static Node[] cut;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
n = input.nextInt();
B = new int[n][3];
x = new int[n];
cut = new Node[n];
for(int j=0; j<3; j++){
String a = input.next();
for(int i=0; i<n; i++)
B[i][j] = a.charAt(i)-'A';
}
for(int i=0; i<n; i++)
x[i] = i;
construct();
backtrack(0);
}
}
private static boolean backtrack(int i){
if(i == n-1){
if(oka()){
for(int j=0; j<n; j++)
System.out.print(x[j]+" ");
return true;
}else
return false;
}else
for(int j=i; j<n; j++){
swap(x,i,j);
if(constrain(i) && backtrack(i+1))
return true;
swap(x,i,j);
}
return false;
}
private static void swap(int[] x, int i, int j){
int tmp = x[i];
x[i] = x[j];
x[j] = tmp;
}
private static boolean oka(){
int carr = 0;
for(int i=n-1; i>=0; i--){
int sum = x[B[i][0]]+x[B[i][1]]+carr;
if(sum%n != x[B[i][2]]) return false;
carr = sum/n;
}
return true;
}
private static boolean constrain(int i){
for(int j=0; j<=i; j++){
if(vio(cut[j]))
return false;
}
return true;
}
private static boolean vio(Node p){
while (p != null){
if((x[p.a]+x[p.b])%n != x[p.c] && (x[p.a]+x[p.b]+1)%n != x[p.c])
return true;
p = p.next;
}
return false;
}
private static void construct(){
Node p;
for(int i=0; i<n; i++)
cut[i] = null;
for(int i=0; i<n; i++){
int maxi = B[i][0];
for(int j=1; j<3; j++)
if(maxi < B[i][j])
maxi = B[i][j];
p = new Node();
p.a = B[i][0];
p.b = B[i][1];
p.c = B[i][2];
p.next = cut[maxi];
cut[maxi] = p;
}
}
}
Input & Output
5
ABCED
BDACE
EBBAA
1 0 3 4 2
7
BCEFDAG
CABGEDF
GDGFAGG
1 2 4 5 3 0 6
Reference
王晓东《计算机算法设计与分析》

本文介绍了虫蚀算式问题,即通过剩余数字推断被虫蛀部分,以解决这类问题。文章提供了问题描述,指出通常假设所有数字被蛀,但知道哪些数字相同,并且算式为n进制加法。通过编程实现,利用回溯法来确定虫蚀算式的缺失数字。数据输入包括n进制和三个包含n个大写字母的字符串,代表两个加数和它们的和,相同的字母表示相同数字。
2721

被折叠的 条评论
为什么被折叠?



