3-12 圈乘运算问题
问题描述
关于整数的 2 元圈乘运算⨂⨂定义为
(X⨂⨂Y)=10 进制整数 X 的各位数字之和××10进制整数Y 的最大数字++Y的最小数字。 例如,(930)=9*3+0=27。
对于给定的10进制整数X和K,由X和⨂⨂运算可以组成各种不同的表达式。试设计一个算法,计算出由 X 和⨂⨂运算组成的值为 K 的表达式最少需用多少个⨂⨂运算。
Java: version 1
import java.util.Scanner;
public class QuanChengYunSuan {
private static int kk;
private static int len;
private static int big;
private static int[][] num;
private static String s1,s2;
private static int MAX = 100000;
public static void main(String[] args){
if(input())
init();
else
return;
compute();
}
private static void compute(){
boolean flag = true;
while (flag){
flag = false;
for(int i=0; i<big; i++)
if(num[i][0] < MAX)
for(int k=0; k<big; k++)
if(num[k][0] < MAX){
int j = num[i][3]*num[k][2]+num[k][1];
if(num[i][0]+num[k][0]+1 < num[j][0]){
num[j][0] = num[i][0]+num[k][0]+1;
flag = true;
}
}
}
if(num[kk][0] < MAX)
out(num[kk][0]);
else
out(-1);
}
private static boolean input(){
Scanner input = new Scanner(System.in);
s1 = input.next();
s2 = input.next();
if(s1.equals(s2)){
out(0);
return false;
}
len = s1.length();
big = 81*len+9;
if(big < 171)
big = 171;
int biglen = (int)Math.ceil(Math.log10(big));
if(s2.length() > biglen) {
out(-1);
return false;
}
kk = Integer.parseInt(s2);
if(kk > big){
out(-1);
return false;
}
return true;
}
private static int ctoi(char x){
return (int)x - 48;
}
private static void out(int x){
if(x >= 0)
System.out.println("The number of X is: "+x);
else
System.out.println("No answer!");
}
private static void init(){
num = new int[++big][4];
for(int i=0; i<big; i++){
num[i][0] = MAX;
num[i][1] = MAX;
num[i][2] = 0;
num[i][3] = 0;
}
for(int i=0; i<len; i++)
count(ctoi(s1.charAt(i)), 0);
num[0][0] = 0;
for(int i=1; i<big; i++){
int t = i;
while (t > 0){
int j = t%10;
t /= 10;
count(j, i);
}
}
}
private static void count(int i, int j){
if(i < num[j][1])
num[j][1] = i;
if(i > num[j][2])
num[j][2] = i;
num[j][3] += i;
}
}
Java: version 2
import java.util.Scanner;
public class QuanChengYunSuan2 {
public static int kk,len,big,biglen,sum;
public static int[] leftn;
public static int[][] rightn;
public static String s1;
public static String s2;
private static int MAX = 1000000;
public static void main(String[] args){
if(input())
init();
else
return;
compute();
}
private static void compute(){
int a, b, c, best = MAX;
int[] abc = new int[3];
boolean flag = true;
while (flag){
flag = false;
for(int i=0; i<=biglen; i++)
if(leftn[i] < MAX)
for(int j=0; j<10; j++)
for(int k=0; k<=j; k++)
if(rightn[k][j] < MAX){
int num;
if(i > 0)
num = i*j+k;
else
num = sum*j+k;
trans(num, abc);
// a = abc[0];
// b = abc[1];
// c = abc[2];
int curr = leftn[i] + rightn[k][j] + 1;
if(curr < leftn[abc[2]]){
leftn[abc[2]] = curr;
flag = true;
}
if(curr < rightn[abc[0]][abc[1]]){
rightn[abc[0]][abc[1]] = curr;
flag = true;
}
if(num == kk && curr < best){
best = curr;
flag = true;
}
}
}
if(best < MAX)
out(best);
else
out(-1);
}
private static void trans(int t, int[] abc){
abc[0] = MAX;
abc[1] = 0;
abc[2] = 0;
while (t > 0){
int j = t%10;
t /= 10;
count(j, abc);
}
}
private static boolean input(){
Scanner input = new Scanner(System.in);
s1 = input.next();
s2 = input.next();
if(s1.equals(s2)){
out(0);
return false;
}
len = s1.length();
big = 81*len+9;
if(big < 171)
big = 171;
biglen = (int)Math.ceil(Math.log10(big));
if(s2.length() > biglen) {
out(-1);
return false;
}
kk = Integer.parseInt(s2);
if(kk > big){
out(-1);
return false;
}
return true;
}
private static void init(){
biglen *= 9;
rightn = new int[10][10];
for(int i=0; i<10; i++)
for(int j=0; j<10; j++)
rightn[i][j] = MAX;
leftn = new int[biglen+1];
for(int i=1; i<=biglen; i++)
leftn[i] = MAX;
int a = MAX, b = 0;
sum=0;
int[] abc = new int[3];
abc[0] = a;
abc[1] = b;
abc[2] = sum;
leftn[0]=0;
for(int i=0; i<len; i++)
count(ctoi(s1.charAt(i)), abc);
a = abc[0];
b = abc[1];
sum = abc[2];
rightn[a][b] = 0;
if(sum <= biglen)
leftn[sum] = 0;
}
private static int ctoi(char x){
return (int)x - 48;
}
private static void out(int x){
if(x >= 0)
System.out.println("The number of X is: "+x);
else
System.out.println("No answer!");
}
private static void count(int i, int[] abc){
if(i < abc[0])
abc[0] = i;
if(i > abc[1])
abc[1] = i;
abc[2] += i;
}
}
Input & Output
3 12
The number of X is: 1
Reference
王晓东《计算机算法设计与分析》(第3版)P92-93

博客探讨了圈乘运算问题,定义为X⨂⨂Y等于X的数字之和乘以Y的最大和最小数字。文章提供了两种Java实现,旨在解决如何找到使用最少圈乘运算得到特定值K的算法。内容引用自王晓东的《计算机算法设计与分析》。
1万+

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



