演算法競賽入門經典習題2-2 水仙花數 2-3韓信點兵
阿新 • • 發佈:2019-01-28
演算法競賽入門經典習題2-2 水仙花數
重定向版並不需要#define LOCAL,fopen版要有檔案才能開啟
</pre><pre code_snippet_id="217260" snippet_file_name="blog_20140304_1_1775024" name="code" class="cpp"></pre><pre code_snippet_id="217260" snippet_file_name="blog_20140304_1_1775024" name="code" class="cpp">/*#include<cstdio> #pragma warning(disable:4966) void main() { for(int n=100;n<1000;n++) { int ge=n%10; int shi=(n/10)%10; int bai=n/100; int s=ge*ge*ge+shi*shi*shi+bai*bai*bai; if(s==n) printf("%d ",n); } }*/ //#define LOCAL//C4966的錯誤 #include<cstdio> #pragma warning(disable:4966) void main() { FILE *fout; fout=fopen("data.out","wb"); for(int n=100;n<1000;n++) { int ge=n%10; int shi=(n/10)%10; int bai=n/100; int s=ge*ge*ge+shi*shi*shi+bai*bai*bai; if(s==n) fprintf(fout,"%d ",n); } fclose(fout); } //#define LOCAL//編譯選項中定義 /*#include<cstdio> #pragma warning(disable:4966) void main() { #ifdef LOCAL freopen("daffodil.out","w",stdout); #endif for(int n=100;n<1000;n++) { int ge=n%10; int shi=(n/10)%10; int bai=n/100; int s=ge*ge*ge+shi*shi*shi+bai*bai*bai; if(s==n) printf("%d ",n); } }*/ /*#pragma warning(disable:4966) #include<cstdio> int main() { FILE *fout; fout=fopen("daffodil.out","wb"); int a,b,c,m; for(a=1;a<=9;a++) { for(b=0;b<=9;b++) { for(c=0;c<=9;c++) { m=a*a*a+b*b*b+c*c*c; if(m==a*100+b*10+c) fprintf(fout,"%d\r\n",m); } } } fclose(fout); return 0; } */
演算法競賽入門經典2-3韓信點兵
主要是要知道解決此題的演算法:
信點兵是一個有趣的猜數遊戲。如果你隨便拿一把蠶豆(數目約在100粒左右),先3粒3粒地數,直到不滿3粒時,把餘數記下來;第二次再5粒5粒地數,最後把餘數記下來;第三次是7粒一數,把餘數記下來。然後根據每次的餘數,就可以知道你原來拿了多少粒蠶豆了。不信的話,你還可以試驗一下。例如,假如3粒一數餘1粒,5粒一數餘2粒,7粒一數餘2粒,那麼,原有蠶豆有多少粒呢? 這類題目看起來是很難計算的,可是我國古時候卻流傳著一種演算法,名稱也很多,宋朝周密叫它“鬼谷算”,又名“隔牆算”;楊輝叫它“剪管術”;而比較通行的名稱是“韓信點兵”。最初記述這類演算法的是一本名叫《孫子算經》的書,後來在宋朝經過數學家秦九韶的推廣,又發現了一種演算法,叫做“大衍求一術”。這在數學史上是極有名的問題,外國人一般把它稱為“中國剩餘定理”。至於它的演算法,在《孫子算經》上就已經有了說明,而且後來還流傳著這麼一道歌訣: 三人同行七十稀, 五樹梅花廿一枝, 七子團圓正半月, 除百零五便得知。 這就是韓信點兵的計算方法,它的意思是:凡是用3個一數剩下的餘數,將它用70去乘(因為70是5與7的倍數,而又是以3去除餘1的數);5個一數剩下的餘數,將它用21去乘(因為21是3與7的倍數,又是以5去除餘1的數);7個一數剩下的餘數,將它用15去乘(因為15是3與5的倍數,又是以7去除餘1的數),將這些數加起來,若超過105,就減掉105,如果剩下來的數目還是比105大,就再減去105,直到得數比105小為止。這樣,所得的數就是原來的數了。根據這個道理,你可以很容易地把前面的五個題目列成算式: 1×70+2×21+2×15-105 =142-105 =37 因此,你可以知道,原來這一堆蠶豆有37粒。 1900年,德國大數學家大衛·希爾伯特歸納了當時世界上尚未解決的最困難的23個難題。後來,其中的第十問題在70年代被解決了,這是近代數學的五個重大成就。據證明人說,在解決問題的過程中,他是受到了“中國剩餘定理”的啟發的。
#include<cstdio> #pragma warning(disable:4996) void main() { FILE *fin,*fout; fin=fopen("data.in","rb"); fout=fopen("data.out","wb"); int a,b,c; int result; scanf("%d %d %d",&a,&b,&c); result=a*70+b*21+c*15; while(result>100) result-=105; if(result<10) fprintf(fout,"No answer\n"); else fprintf(fout,"%d\n",result); fclose(fin); fclose(fout); }//要有data.in的檔案 //#define LOCAL /*#include<cstdio> #pragma warning(disable:4996) #include<iostream> using namespace std; int main() { #ifdef LOCAL freopen("data.in","r",stdin); freopen("data.out","w",stdout); #endif int a,b,c; int result; //scanf("%d%d%d",&a,&b,&c); cin>>a>>b>>c; result=a*70+b*21+c*15; while(result>100) result-=105; if(result<10) printf("No answer\n"); else printf("%d\n",result); fclose(stdin); fclose(stdout); return 0; }*/ /*#pragma warning(disable:4996) #include<stdio.h> int main() { FILE *fin,*fout; fin=fopen("hanxin.in","rb"); fout=fopen("hanxin.out","wb"); //fin=stdin; //fout=stdout; int a,b,c,x,temp=0;//temp用來判斷是否在10到100記憶體在這樣的數 fscanf(fin,"%d%d%d",&a,&b,&c); for(x=10;x<=100;x++) { if(x%3==a&&x%5==b&&x%7==c) { fprintf(fout,"%d\r\n",x); temp=1; break; } } if(!temp)fprintf(fout,"No answer\r\n"); fclose(fin); fclose(fout); return 0; }*/