USACO 1.3.4 Prime Cryptarithm 牛式 JAVA实现
也许我要从CSDN转移到这里来了。
这道题可以很自然地想到,得到用到的数字后,把这些数字对每一个的位置的情况进行遍历,两个月前我用C++做题时打算这么做过,后来因为严重超时而放弃;另一种方式就巧妙多了:既然数字的位数已经指定了, 可以遍历三位数与二位数的组合,再从中选择符合条件的。
总得来说是第一个for循环遍历所有三位数,判断这个三位数是不是由可用数字组成的;如果是,那么进入第二个for循环遍历二位数,判断二位数的是否由可用数字组成;接着判断三位数和二位数的个位的乘积,三位数和二位数十位的乘积,总的乘积。注意每个乘积都有位数要求,所以不妨增加个大小限制,相当于进行了剪枝。
针对JAVA的特性,我觉得最方便的是判断三位数每个位置上的数字是不是可用的数字,在这里可以把包装器类的Integer转化成字串,再通过toString以及charAt获取指定位置上的数字。至于具体的判断方式,我的做法是用一个标记数组,如果9是可用的,那么num[9]就是true。
1 package primeCrypt; 2 3 import java.util.Arrays; 4 import java.util.Scanner; 5 6 //输入数据 7 // 输入第一个数字 8 // 输入接下来的可用数字 9 // 运用标记 10 // 数字标记数组 11 // 12 //遍历所有三位数 13 // 遍历所有二位数 14 // 检查第一个步骤积 15 // 检查第二个步骤积 16 // 检查最终的结果 四位 17 18 19 public class Main { 20 static int n; 21 static boolean[] numbers= new boolean[10]; 22 public static void main(String[] args) { 23 Scanner console= new Scanner(System.in); 24 n= console.nextInt(); 25 26 for(int i=0; i<10; i++) {//初始化 27 numbers[i]= false; 28 } 29 30 int num; 31 for(int i=0;i<n; i++) {//设置有效数字 32 num= console.nextInt(); 33 numbers[num]= true; 34 } 35 36 int countN= 0; 37 for(Integer i=100; i<=999; i++) { 38 boolean signOk1= true; 39 //讨论三位数可行性 40 for(int s=0; s<=2; s++) { 41 if(numbers[i.toString().charAt(s)-'0']==false) { 42 signOk1= false;break; 43 } 44 } 45 if(signOk1== false) continue;//不可行提前终止 46 47 //讨论二位数可行性 48 for(Integer j=10; j<=99; j++) { 49 boolean signOk2= true; 50 for(int s=0; s<=1; s++) { 51 if(numbers[j.toString().charAt(s)-'0']==false) { 52 signOk2= false;break; 53 } 54 } 55 if(signOk2== false) continue;//不可行提前终止 56 57 //讨论第一个积的可行性 58 boolean signOk3= true; 59 Integer prdt1= i* (j.toString().charAt(1)-'0'); 60 if(prdt1>999) continue; 61 for(int s=0; s<=2; s++) { 62 if(numbers[prdt1.toString().charAt(s)-'0']==false) { 63 signOk3= false; 64 } 65 } 66 if(signOk3== false)continue; 67 68 //讨论第二个积的可行性 69 boolean signOk4= true; 70 Integer prdt2= i* (j.toString().charAt(0)-'0'); 71 if(prdt2>999) continue; 72 for(int s=0; s<=2; s++) { 73 if(numbers[prdt2.toString().charAt(s)-'0']==false) { 74 signOk4= false; 75 } 76 } 77 if(signOk4== false)continue; 78 79 //讨论第三个积的可行性 80 boolean signOk5= true; 81 Integer prdt3= i* j; 82 if(prdt3>9999) continue; 83 for(int s=0; s<=2; s++) { 84 if(numbers[prdt3.toString().charAt(s)-'0']==false) { 85 signOk5= false; 86 } 87 } 88 89 if(signOk5== true) countN++; 90 } 91 } 92 System.out.println(countN); 93 } 94 }

浙公网安备 33010602011771号