您的位置:首页 > 其它

欧拉工程第42题:Coded triangle numbers

2015-05-25 18:46 281 查看
题目链接:https://projecteuler.net/problem=42

三角形数序列中第 n 项的定义是: tn = ½n(n+1)

26个字母对应其依次出现的顺序,如A:1,B:2

如果一个单词,各个字母对应数字之和在三角形数序列中,则这个单词是三角形单词。

求给的txt文件中有多少个单词

思路:

1.读取txt文件

2.判断是否是三角形单词

3.统计个数

如何判断是三角形单词?

1.求出单词对于的数是多少,这个比较简单

2.判断这个数是否在三角形数序列中

如何判断一个数是在三角形序列中?

1.暴力破解

对1到n的数分别求½n(n+1) 若等于所要判定的数,则是三角形数。

太暴力,时间长,本题让判断的数有2000左右的。

2.巧解

tn = ½n(n+1),我们假设输入的数num是三角形数,则num= ½n(n+1),根据这个我们可以求出n,再判断n对于的真实的三角形数tn是否等于num,等于则是三角形数。

n=1+8tn√−12n=\frac{\sqrt{1+8tn}-1}{2} OK



n=−1+8tn√−12n=\frac{-\sqrt{1+8tn}-1}{2} 显然不对,都小于0了

这个也可以,比方法一好多了

3.不直接求n

num= ½n(n+1)

2*num=n*n+n

看到这个式子,突然感觉当n趋向无穷大时候 2*num = n * n

2*num = n * n 是关键

所有 n=sqrt(2*num) 四舍五入

这里的问题要是n是很大的数才满足条件

手工试了下,发现n=1到10都满足。为什么?

我们可以考虑下面两个数的关系,左边的是我们认为的n,右边实际的n,假设小于

2∗num−−−−−−−√\sqrt{2*num} < 1+8num√−12\frac{\sqrt{1+8num}-1}{2}

化简后:

0<1-21+8num−−−−−−−−√\sqrt{1+8num}

21+8num−−−−−−−−√\sqrt{1+8num}<1

假设错误

2∗num−−−−−−−√\sqrt{2*num} > 1+8num√−12\frac{\sqrt{1+8num}-1}{2}

这个还不足以说明问题,注意到我们用到了四舍五入,下面证明

2∗num−−−−−−−√\sqrt{2*num} < 1+8num√−12+12\frac{\sqrt{1+8num}-1}{2}+\frac{1}{2}

2∗num−−−−−−−√\sqrt{2*num} < 1+8num√2\frac{\sqrt{1+8num}}{2}

两边平方后整理:1>0

即:

1+8num√−12\frac{\sqrt{1+8num}-1}{2} <2∗num−−−−−−−√\sqrt{2*num} < 1+8num√−12+12\frac{\sqrt{1+8num}-1}{2}+\frac{1}{2}

所有再加上四舍五入2∗num−−−−−−−√\sqrt{2*num}就是我们求的n

Java代码:

package projecteuler41to50;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;

class level42{
void solve() throws IOException{
int result=0;

String filename="src\\projecteuler41to50\\p042_words.txt";
String[] WordString=ReadTxt(filename);
for(int i=0;i<WordString.length;i++){
String word=WordString[i];
int wordTonum=WordToNumber(word);
if(isTriang(wordTonum)==true){
result+=1;
}
}
System.out.println("result:"+result);
}
int WordToNumber(String Word){
int sum=0;
for(int i=0;i<Word.length();++i){
String letter=Word.substring(i, i+1);
sum+=LetterToNumber(letter);
}
return sum;
}
boolean isTriang(int tn){
int n=(int)Math.sqrt(2*tn);
if(n*(n+1)==2*tn)
return true;
return false;
}
int LetterToNumber(String letter){
letter=letter.toLowerCase();
return letter.hashCode()-"a".hashCode()+1;
}
String[] ReadTxt(String filename) throws IOException{
File fl=new File(filename);
BufferedReader reader=null;
String tempString=null;
String WordString="";
String[] WordArray;

try {
reader=new BufferedReader(new FileReader(fl));
while((tempString=reader.readLine())!=null){
WordString+=tempString;

}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WordString=WordString.replaceAll("\"", "");
WordArray=WordString.split(",");
return WordArray;
}

}
public class Problem42 {

public static void main(String[] args) throws IOException{
Date beginTime=new Date();
new level42().solve();
Date endTime=new Date();
Long Time=endTime.getTime()-beginTime.getTime();
System.out.println("Time:"+Time/1000+"s"+Time%1000+"ms");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: