C语言经典编程282例08

045 求二元一次不定方程

求解二元一次不定方程ax + by = c 的解,其中a、 b 、 c要求从键盘中输入,其中a>0,b>0且a>=b,

  • 定理1:现有不定方程a * x + b * y = c,a,b,c均为整数,若d=GCD(a,b)(GCD表示取a,b的最大公约数),d|c(d整除c),那么二元一次不定方程必定有解,且有无数解。
    在这里插入图片描述
  • 定理2:若不定方程a * x + b * y = c有整数解,则通解的形式必定为X=x0 + b/d * n, Y = y0 - a/d * n。其中x0,y0为不定方程的一个整数解。
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>


void result (int a, int b, int c, int *x2, int *y2)
{
	int x[100], y[100], z[200];
	int i, j, d, t, gcd;
	x[0] = 0;
	y[0] = 1;
	
	for(i = 0; i < 100; i++)
	{
		z[i] = a / b;
		d = a % b;
		a = b;
		b = d;
		
		if(d == 0)
		{
			gcd = a;                  //辗转法求最大公约数
			break;
		}
		
		if(i == 0)              	 //判断a是否被b整除
		{
			x[1] = 1;
			y[1] = z[0];
		}
		else
		{
			x[i + 1] = z[i] * x[i] + x[i - 1];
			y[i + 1] = z[i] * y[i] + y[i - 1];
		}
	}
	
	for(t = -1, j = 1; j < i; j++)
	{
		t = -t;	
	}
	
	*x2 = -t * x[i];
	*y2 = t * y[i];
	
	if(c % gcd != 0)			//判断c是否能够整除a和b最大公约数
	{
		printf("无解\n");
		exit(0); 
	}
	
	t = c / gcd;
	*x2 = *x2 * t;
	*y2 = *y2 * t;
}

 void test(int a, int b, int c, int x, int y)
 {
 	if(a * x + b * y == c )
 	{
 		printf("结果正确\n");
	 }
	 else
	 {
	 	printf("结果错误\n");
	  } 
 }

  main()
{
   int a, b, c, x2, y2;
   printf("输入a, b, c:\n");
   scanf("%d%d%d", &a, &b, &c);
   
   result(a, b, c, &x2, &y2);
   
   test(a, b, c, x2, y2);
   printf("x = %d, y = %d\n",x2, y2);  
   
	printf("\n");
 }
 

046 可逆素数

可逆素数:将一个素数的各位数字顺序地倒过来构成地反序数仍然是素数

// —————————————— 官方————————————————————
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

int ss(int s)
{
	int n;
	
	if(s == 1)
	{
		return 0;
	}
	
	if(s == 2)
	{
		return 1;
	}
	
	for(n = 2; n < s; n++)
	{
		if(s % n == 0)
		{
			return 0;
		}
		else if(s != n + 1)
		{
			continue;	
		}
		else 
		{
			return 1;
		}
	}
	
}


  main()
{
   int a = 0, i, n = 0, n1, n2, n3, n4;
   
   for(i = 1000; i <= 9999; i++)
   {
	   if( ss(i) == 1)
	   {
	   ///这个将数逆反推荐
	   	  n4 = i % 10;
	   	  n3 = (i % 100 ) / 10;
	   	  n2 = (i / 100) % 10;
	   	  n1 = i / 1000;
	   	  
		  
		  if(ss(1000 * n4 + 100 * n3 + 10 * n2 + n1) == 1 && (1000 * n4 + 100 * n3 + 10 * n2 + n1) > i )
		  {
		  	n++;
		  	printf(" %d ", i);
		  	if(n % 10 == 0)
		  	{
		  		printf("\n");
			}
		  }
		
		}	
   	
   } 
	printf("\n");
 }
/     ——————————————————      ME __________________
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

int ss(int s)					//自定义函数判断是否为素数
{
	int n;
	
	if(s == 1)
	{
		return 0;
	}
	
	if(s == 2)
	{
		return 1;
	}
	
	for(n = 2; n < s; n++)					对大于2的数进行判断
	{
		if(s % n == 0)
		{
			return 0;
		}
		else if(s != n + 1)
		{
			continue;	
		}
		else 
		{
			return 1;
		}
	}
	
}

  main()
{
   int a, i, j, t, b, n;
   
   for(i = 1000; i <= 9999; i++)
   {
       a = ss(i);
	
	   if(a == 1)
	   {
	   	  j =i;							//取千位
	   	  t = j / 1000;
	   	  j = j % 1000;
	   	  b = t ;
			  
	   	  t = j / 100;					//取百位
	   	  j = j % 100;
	   	  b += t * 10;
	   	 
	   	  
	   	  t = j / 10;					//取十位
	   	  j = j % 10; 					//取个位
	   	  b += t * 100;
	   	  b += j * 1000;
	   	
		  a = ss(b);					//判断逆反是不是素数
		  
		  if(a == 1  && b > i)
		  {
		  	n++;
		  	printf(" %d ", i);
		  	if(n % 5 == 0)
		  	{
		  		printf("\n");
			}
		  }
		
		}	
   	
   } 
	printf("\n");
 }
 

048 判断闰年

从键盘上输入一个表示年份的整数,判断该年份是否闰年。

  • 公元年分非4的倍數,為平年,或
  • 公元年分為4的倍數但非100的倍數,为闰年,或
  • 公元年分為100的倍數但非400的倍數,为平年,或
  • 公元年分為400的倍數但非3200的倍數,为闰年,或
  • 公元年分為3200的倍數但非80000年的倍數,為平年,或
  • 公元年分為80000的倍數為閏年。

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
   int year = 0 ;
   
   scanf("%d", &year);
   
   //判断条件
   if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
   	 printf("%d是闰年", year);
   }
   else
   {
     printf("%d是平年", year);
   }
   
   
	printf("\n");
 }
 

在这里插入图片描述

049 黑纸与白纸

有A\B\C\D\E 五个人,每个人额头上都贴了一张黑色或白色的纸,5人相对而坐,每个人可以看见其他额头上的纸颜色,但都不知道自己额头上纸的颜色,
A:“我看见有3个人额头上贴的是白纸,一个人贴黑。
B:"我看见其他4人贴都是黑纸
C:”我看见一个人贴白色,其他3人黑色
D:"我看见4人贴白色
E:“我不发表
现在知道头贴黑纸人说假话,贴白纸人说真话,问各自贴的纸?
在这里插入图片描述
在这里插入图片描述


#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
   int a, b, c, d, e;
  
   for(a = 0; a <= 1; a++)
   {
   	 for(b = 0; b <= 1; b++)
   	 {
   	   for(c = 0; c <= 1; c++)
	   {
	   	 for(d = 0; d <= 1; d++)
	   	 {
	   	 	for(e = 0; e <= 1; e++)
	   	 	{
	   	 	//判断条件
	   	 		if(((a && b + c + d + e == 3) || (!a && b + c + d + e != 3)) 
					&& ((b && a + c + d + e == 0) || (!b && a + c + d + e != 0))
					&& ((c && b + a + d + e == 1) || (!c && b + a + d + e != 1))
					&& ((d && b + c + a + e == 4) || (!d && b + c + a + e != 4)))
					{
						printf("a = %d ; b= %d ; c= %d; d=%d; e=%d",a, b, c, d, e);
					}
	   	 		## 标题
			}
	     } 
			  
	   }	
	 }
   }
   
   
	printf("\n");
 }
 

049 阿姆斯特朗数

阿姆斯特朗数:水仙花数,是指一个三位数,其各数字的立方和等于该数本身,例如:153是一个水仙花数,因为 153 = 1立方+ 5 立方+ 3立方。
编程求出所有水仙花数。

//官方
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
   int i, n1, n2, n3;
   
   for(i = 100 ; i <= 999; i++)
   {
   	  n1 = i % 10;
   	  n2 = (i % 100) / 10;
   	  n3 = i / 100;
   	  if(n1 * n1 *n1 + n2 * n2 * n2 + n3 * n3 * n3 == i)
   	  {
   	  	printf("%5d\n",i);
	  }
	 
   }
  
	printf("\n");
 }
//———————————————— ME——————————————for 中没有将sum 赋初值,导致sum变量一直增加,导致sum 不会= i.


#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
   int i, sum = 0, n = 0;
   
   for(i = 100 ; i <= 999; i++)
   {
   	  sum = 0;
   	  n = i % 10;
   	  sum += (int)pow(n, 3);
   	  
   	  n = (i % 100) / 10;
   	  sum += (int)pow(n, 3);
   	  
   	  n = i / 100;
   	  sum +=(int) pow(n, 3);
   	  
   	  if(sum == i)
   	  {
   	  	printf("%5d\n",i);
	  }
   }

	printf("\n");
 }

050 最大公约数和最小公倍数

从键盘中输入两个正整数a和b,求其最大公约数和最小公倍数

s最小公倍数=两整数的乘积/最大公约数

最小公倍数:
  两个或多个[整数]公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
  
最大公约数:
  两个或多个[整数]公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。

辗转相除法
有两整数a和b:

  • a%b得余数c
  • 若c=0,则b即为两数的最大公约数
  • 若c≠0,则a=b,b=c,再回去执行1
//
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
   int a, b, t, c, m;
   
   scanf("%d%d", &a, &b);
   
   if(a < b)
   {
   	 t = b; 
   	 b = a;
   	 a = b;
   }
   
   m =a * b;         		//保存两数乘积,以备求公倍数使用
   c = a % b;
   
   while(c != 0)
   {
   	 a = b;
   	 b = c;
   	 c = a % b;
   }
   
   printf("最大公约数%d\n", b);
   printf("最大公倍数%d\n",  m / b);
   printf("\n");
 }
 

051 求一元二次方程的根

求一元二次方程ax平方 +bx + c=0/的根,由键盘输入系数求根
提示:这种问题类似给出公式计算,可以按照输入数据、计算、输出三步方案来设计运行程序:

在这里插入图片描述在这里插入图片描述


#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    double a, b, c, d, x1, x2;
    
    scanf("%lf%lf%lf", &a, &b, &c); ///在该处忘记加&取地址符,以及输入的%错误。
    
    d = b * b - 4 * a * c;
    
    if(d > 0)
    {
    	x1 = (- b + sqrt(d)) / (2 * a);
    	x2 = (- b - sqrt(d)) / (2 * a);
    	printf("x1= %f, x2= %f\n", x1, x2);
	}
	else if(d == 0)
	{
		x1 = x2 = -(b / (2 * a)) ;
		printf("x1= %f, x2= %f\n", x1, x2);
	}
	else if(d < 0)
	{
		printf("该方程无解\n");
	}
    
	printf("\n");
 }
 

052 自然对数的底e的计算

自然数对数的底 e= 2.71828128… ,e的计算公式是e = 1 + 1/ 1! + 1/2 ! + 1/3 !+…,要求当最后一项小于10 (-10)次方时结束/


#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    float e = 1.0 , n = 1.0;
    int i =1;
    
    while(1 / n > pow(10,-10) )
    {
    	e += 1 / n;
    	i++;
    	n = i * n; 			//阶乘
	}
	
	printf("%f",e);
   
	printf("\n");
 }

053 满足 abcd = (ab + cd )平方的数

假设abcd 是一个四位数,将它分成2段,即ab和cd,使之相加求和再平分,求满足该关系的四位数。

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    int abcd, ab, cd;
    
    for(abcd = 1000; abcd <= 9999; abcd++)
    {
    	//分别计算2位数:
    	ab = abcd / 100;		
    	cd = abcd % 100;
    	
    	if(abcd == (ab + cd) * (ab + cd))
    	{
    		printf("%d\n", abcd);
		}
	}
   
	printf("\n");
 }

054 整数加减法练习

练习者自己选择是进行加法还是减法运算,然后输入进行多少以内的加法或减法运算,具体数值会由计算机随机产生,输入答案,计算机会根据输入的数据判断结果是否正确。

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    int a, b, c, sign, max;
    char sign1;
    printf("请选择运算符(1 or other; 1 : -, other : +) \n");
    scanf("%d", &sign);
    printf("请选择最大的数(< 10000) \n");
    
    scanf("%d", &max);
    srand((unsigned long )time(0));
    
    a = rand() % max;
    b = rand() % max;
    
    while((a < b) && (sign == 1))
    {
    	a = rand() % max;
    	b = rand() % max;
	} 
	
	sign1 = (sign == 1?'-':'+');
	printf("\n %d%c%d=", a, sign1, b);
	scanf("%d", &c);
	if((sign == 1) && (a - b == c) || (sign != 1) && (a + b == c) )
	{
		printf("计算正确\n");
	}
	else
	{
		printf("计算错误\n");
	 } 
    
   
	printf("\n");
 }

055 判断整数倍

编程判断输入的数是否既是5又是7的整数倍,如果是输出YES,不是输出NO。


#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    int a;
    scanf("%d", &a);
	
	if(a % 7 == 0 && a % 5 == 0)
	{
		printf("YES \n");
	 } 
	 else
	 {
	 	printf("NO \n");
	 }
   
	printf("\n");
 }
 

056 阶梯问题

在你面前有一条长长的阶梯:如果每步跨2阶;那么最后剩1阶;如果每步跨3阶;那么最后剩2阶;如果每步跨5阶;那么最后剩4阶;如果每步跨6阶;那么最后剩5阶;只有每步跨7阶,最后才正好走完,一阶不剩,请问这条阶梯至少有多少阶?(求所有3位阶梯数)

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    int i;
    for(i = 100; i <= 999; i++)
    {
    //判断:
    	if(i % 2 == 1 && i % 3 == 2 && i % 5 == 4 && i % 6 == 5 && i % 7 == 0)
    	{
    			printf("阶梯数: %d\n", i);
		}
	}
   
	printf("\n");
 }

057 乘积大于和的数

编程求10~ 100之间满足各位上数的和的所有数,并将结果以每行5个的形式输出,

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    int i, m = 0, k = 0, s = 1, n = 0;
    for(i = 10; i <= 100; i++)
    {
    	s = 1;
    	k = 0;
    	m = i;
    	while(m)
    	{
    		s *= m % 10;
    		k += m % 10;
    		m /= 10;
    		
		}
		
		if(s > k)
		{
			n++;
			printf("数:%d", i);
			
			if(n % 5 == 0)
			{
				printf("\n");
			}
		}
	} 
	printf("\n");
 }

在for语句中,忘记赋s,k 的初始值值(只在变量初始化中赋值),这造成执行后面的循环中的 s、k承接上一个s,k的值。

058 求各位数之和为5的数

编程求100~1000之间满足各数字之和是5的所有数,以5个数字的形式输出。

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

  main()
{
    int i, m = 0, sum = 0, n = 0;
    for(i = 100; i <= 1000; i++)
    {
        sum = 0;
        m = i;
        
    	while(m)
    	{
    		sum += m % 10;
    		m /= 10;		
		}
		
		if(sum == 5)
		{
			n++;
			printf("数:%d", i);
			
			if(n % 5 == 0)
			{
				printf("\n");
			}
		}
	}
   
	printf("\n");
 }

一些技术要点:https://blog.csdn.net/qq_41070511/article/details/110677069
参考文献:
二元一次不定方程的快速解法:https://blog.csdn.net/uniqueleion/article/details/81280156

最大公约数:
链接:https://www.jianshu.com/p/53a9685eb411

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值