欧拉工程第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代码:
三角形数序列中第 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"); } }
相关文章推荐
- project euler 42 Coded triangle numbers
- Project Euler:Problem 42 Coded triangle numbers
- No42_Coded triangle numbers
- Problem 42 Coded triangle numbers(ifstream +getline)
- 欧拉工程第44题:Pentagon numbers
- Project Euler:Problem 42 Coded triangle numbers
- (Problem 42)Coded triangle numbers
- 欧拉工程第61题:Cyclical figurate numbers
- 欧拉工程第21题:Amicable numbers
- Java 欧拉工程 第二十篇【 算出100!的各位之和。】
- Java 欧拉工程 第二十二篇【 名字得分总和】
- 欧拉工程第41题:Pandigital prime
- 我的欧拉工程之路_9
- 我的欧拉工程之路_15
- 欧拉工程第8题 找出这个1000位数字中连续13个数字乘积的最大值
- 欧拉工程第24题 0,1,2,3,4,5,6,7,8,9的第100万个字典排列是什么
- 欧拉工程第30题:Digit fifth powers
- 欧拉工程第40题: Champernowne's constant
- 我的欧拉工程之路_10
- 欧拉项目 Problem 12 of What is the value of the first triangle number to have over five hundred divisors