通过SecretSum来训练循环能力
来源:互联网 发布:淘宝延迟发货怎么赔偿 编辑:程序博客网 时间:2024/05/16 05:23
Google Gam中有一道题目是SecretSum。题目要求如下:
Problem Statement
We can substitute each digit of a number with a unique letter from 'A' to 'Z'. This way we can write groups of numbers in a single representation. For example "ABA" can represent any of the following: 101, 151, 343, 767, 929. However, "ABA" cannot mean 555 because each letter must stand for a distinct digit. Furthermore, numbers cannot begin with 0 and thus 'A' cannot be replaced by 0.
Given two such representations num1 and num2 and the result of their summation return the total number of possible combinations of numbers for which the equation holds. If no combinations are possible then return 0.
Definition
Class: SecretSum
Method: countPossible
Parameters: string, string, string
Returns: int Method signature:
int countPossible(string num1, string num2, string result)
Constraints
num1, num2, and result will each contain exactly 3 uppercase letters ('A' - 'Z').
Examples
0)
"AAA"
"BBB"
"CCC"
Returns: 32
1)
"ABB"
"DEE"
"TTT"
Returns: 112
2)
"ABC"
"ABA"
"ACC"
Returns: 0
Leading zeroes are not allowed.
3)
"AAA"
"CDD"
"BAA"
Returns: 32
4)
"TEF"
"FET"
"AAA"
Returns: 12
5)
"ABC"
"ABC"
"BCE"
Returns: 5
We can have the following 5 sums:
124 + 124 = 248
125 + 125 = 250
249 + 249 = 498
374 + 374 = 748
375 + 375 = 750
6)
"AAA"
"AAA"
"BBB"
Returns: 4
We can have the following 4 sums:
111 + 111 = 222
222 + 222 = 444
333 + 333 = 666
444 + 444 = 888
初拿到这个题目,感觉没什么好的思路。
再仔细想想,用比较笨的方法也不错。就是做循环,顺次查找,加数一从100到999,其中每次都要求加数二从100到999的子循环,在每次循环过程中,验证数据是否合法。
看来没其它好的思路,这种循环也不错阿。
关键是条件判断如何进行了。根据题意,result<1000,这是一个条件。
然后,过滤加数一的时候,产生一个字母到数字的映射,这个映射要作用到加数二和和数。加数二在这个映射上再加工产生一个映射,然后根据这个映射判断和数是否满足条件。
这两个条件都满足了,才可以pass一种组合。(至于'A'不允许为0,我们从100开始循环就行了,这个题意我是这样理解的)。
好,java写的如下:
public class SecretSum {
public int countPossible(String num1, String num2, String result){
int count = 0;
for(int i = 100; i < 1000; i++){
for ( int j = 100; j < 1000; j ++){
if(isSucceed(num1,num2,result,i,j)){
//System.out.print(count + ":[" + i + "," + j + "]/t");
// if(count %5 == 0)
// System.out.println();
count ++;
}
}
}
return count;
}
//输入两个数,判断是否正确
private boolean isSucceed(String num1, String num2, String result, int n1,int n2){
//条件一:和数要<1000
if(n1 + n2 > 1000)
return false;
//条件二:n1,n2要和num1,num2匹配,而且有附加条件
Map outMap = new HashMap();//附加条件,表示当前确定了的数字字母对应关系
if(samePattern(num1,n1,outMap)
&& samePattern(num2,n2,outMap)
&& samePattern(result,n1+n2,outMap)){
return true;
}
return false;
}
private boolean samePattern(String num, int n,Map outMap) {
//首先,察看千位数num[0]是否已固定
String hundred = num.substring(0,1);
String ten = num.substring(1,2);
String one = num.substring(2,3);
//百位数
int val = n/100;
if(false == mergeVal(val,hundred,outMap))
return false;
//十位数
val = n/10;
val %= 10;
if(false == mergeVal(val,ten,outMap))
return false;
//个位数
val = n%10;
if(false == mergeVal(val,one,outMap))
return false;
return true;
}
boolean mergeVal(int val,String num,Map outMap){
if(outMap.containsKey(num)){
Integer ih =(Integer)outMap.get(num);
if(ih.intValue()!=(val))//如果不相符合
return false;
}
else//没有,则加入
{
Integer iVal = new Integer(val);
//保证无冲突
if(!outMap.containsValue(iVal))
outMap.put(num,iVal);
else
return false;
}
return true;
}
}
来几个测试:
import junit.framework.TestCase;
public class SecretSumTest extends TestCase {
public void testAAABBBCCC(){
SecretSum ss = new SecretSum();
int count = ss.countPossible("AAA","BBB","CCC");
assertEquals(32, count );
}
public void testABBDEETTT(){
SecretSum ss = new SecretSum();
int count = ss.countPossible("ABB","DEE","TTT");
assertEquals(112, count );
}
public void testABCABA(){
SecretSum ss = new SecretSum();
int count = ss.countPossible("ABC","ABA","ACC");
assertEquals(0, count );
}
public void testAAACDDBAA(){
SecretSum ss = new SecretSum();
int count = ss.countPossible("AAA","CDD","BAA");
assertEquals(32, count );
}
public void testTEFFETAAA(){
SecretSum ss = new SecretSum();
int count = ss.countPossible("TEF","FET","AAA");
assertEquals(12, count );
}
public void testABCABCBCE(){
SecretSum ss = new SecretSum();
int count = ss.countPossible("ABC","ABC","BCE");
assertEquals(5, count );
}
}
均通过。
不过耗时较长,大约用了1个小时,主要是不想用这种思路,反复的找其他的巧的思路,这样做着实比较浪费时间。
- 通过SecretSum来训练循环能力
- Android通过循环来findViewById
- 能力训练
- 能力训练
- 普通人如何通过训练大幅提高自己的决策能力?
- 通过限制循环次数来避免死循环
- 通过ab测试抗压能力 和 添加索引来增加搜索 能力
- 新的篇章,通过博客来锻炼技术表达能力,学习能力
- MySQL通过游标来实现通过查询结果集循环
- google竞赛题SecretSum的另一种C++解法, 使用递归生成代替循环 -- 1
- google竞赛题SecretSum的另一种C++解法, 使用递归生成代替循环 -- 2
- 如何高效的通过BP算法来训练CNN
- 能力拓展训练计划
- 能力拓展训练计划
- 表达能力训练
- 抽象思维能力训练随感
- SGU103代码能力训练
- 应用程序通过消息循环来获得对消息的处理
- JS 知识点
- 关于自学和上培训班的问题
- (转载)反病毒引擎设计 --- 实时监控篇
- byte数组和其他数据类型之间的转化
- 获取cpuid
- 通过SecretSum来训练循环能力
- navigation
- Microsoft Announces Beta Availability of ISA Server 2006(ZT)
- Google AdSense Fraud - Deep Insight
- 通过颗粒编号,识别当今现代(HYNIX)内存条规格
- 一个大学生的广州血泪史(一)[转帖]
- 再看BPEL
- 你未必知道的10个CSS技巧(转)
- 一个大学生的广州血泪史(二)[转帖]