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 }

 

posted @ 2020-10-20 22:27  Roswell  阅读(109)  评论(0)    收藏  举报