算法竞赛入门经典习题2-2 水仙花数 2-3韩信点兵

算法竞赛入门经典习题2-2 水仙花数
重定向版并不需要#define LOCAL,fopen版要有文件才能打开

/*#include
#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
#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
#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

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
#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
#pragma warning(disable:4996)
#include
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
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;
}*/



你可能感兴趣的:(算法竞赛入门经典)