算法小合集(一些有趣的数)(二)

例1:求100以内所有的勾股数;(满足勾股定理的3个正整数)

分析:三个数满足 a 2 + b 2 = c 2 a^2+b^2=c^2 a2+b2=c2
按a<b<c进行排列;

#include<stdio.h>
int main()
{
	for (int i = 1;i < 100;i++)
	{
		for (int j = i;j < 100;j++)
		{
			for (int k=j ;k <= 100;k++)
			{
				if (i * i + j * j == k * k)
				{
					printf("%3d%3d%5d是勾股数\n", i, j, k);
				}
			}
		}
	}
	return 0;
}

例2:

一个整数,它加上100后是个完全平方数,在加上168又是一个完全平方数,请问这个数是多少
原理:一个数如果不是整数的平方对,取int他开方再平方会变小,就和原来的数不等了

#include<stdio.h>
#include<math.h>
int main()
{
	int x, y;
	for (int i = 0;i < 100000;i++)
	{
		x = sqrt(i + 100);
		y = sqrt(i + 268);
		if(x*x==i+100&&y*y==i+268)
		{
			printf("%d就是要求的那个数\n", i);
		}
	}
}

例3 求黑洞数

#include<stdio.h>
int MaxOf(int a, int  b, int c)
{
	int t;
	if (a < b)
	{
		t = a;
		a = b;
		b = t;
	}
	if (a < c)
	{
		t = a;
		a = c;
		c = t;
	}
	if (a < c)
	{
		t = b;
		b = c;
		c = t;
	}
	return a * 100 + b * 10 + c;

}
int MinOf(int a, int b, int c)
{
	int t;
	if (a < b)
	{
		t = a;
		a = b;
		b = t;

	}
	if (a < c)
	{
		t = a;
		a = c;
		c = b;
	}
	if (b < c)
	{
		t = b;
		b = c;
		c = t;
	}
	return c * 100 + b * 10 + c;
}
int main()
{
	int num,i, unit, ten, hundred;
	int max, min,gap;
	int temp;
	printf("请输入一个三位数");
	scanf_s("%d", &num);
	unit = num % 10;
	ten = num /10 % 10;
	hundred = num /100 % 10;
	printf("%3d%3d%3d\n", unit, ten,hundred );
	max = MaxOf(unit, ten, hundred);
	min = MinOf(unit, ten, hundred);
	gap = max - min;
	for (i = 0;;i++)
	{
		temp = gap;//记录上一次的差值;
		unit = num % 10;
		ten = num / 10 % 10;
		hundred = num / 100 % 10;
		max = MaxOf(unit, ten, hundred);
		min = MinOf(unit, ten, hundred);
		gap = max - min;
		if (gap == temp)
		{
			printf("%d%d是黑洞数",gap,temp);
			break;
		}
	}
}

例3 求自守数

自守数是指一个数的平方的尾数等于该数自身的自然数
5 2 = 25 , 2 5 2 = 625 , 7 6 2 = 5776 5^2=25,25^2=625,76^2=5776 52=25,252=625,762=5776
c 求100000以内的自守数;
初步想法 ( i ∗ i − i ) / 10 余 0 (i*i-i)/10余0 (iii)/100则是自守数
这个想法是错的,这个条件只是必要条件不是充分条件比如10的平方;
网络版本
自己的分析:假如一个数有n位数;
要得到乘方后n位’
我们来分析一下
可以产生n位数的有哪些
第1次循环***第一位前n位
第2位前n-1位**

第i次循环第i位* 第n+1-i位 **;
比如123123
为了得到一个3位数
3 ∗ 123 3*123 3123
2 ∗ 10 ∗ 23 2*10*23 21023
1 ∗ 10 ∗ 10 ∗ 3 1*10*10*3 110103
然后加起来%1000即为所得
因为比如999
999;
会 有 9 ∗ 10 ∗ 10 ∗ 9 = 8100 会有9*10*10*9=8100 910109=8100
让我们最终只要百位;
只有最大位数的数乘起来可能会比要的位数多,所以要取一次余数
于是我们知道我们需要什么

  1. 该数的第i位数
  2. 该数的前n+1-i位数
#include<stdio.h>
int judge(int n)//判断量级的函数
{
	int count = 1;
	while (n != 0)
	{
		count*=10;
		n = n / 10;
	}
	return count;

}
int judge2(int n)
{
	int count = 0;
	while (n != 0)
	{
		count++;
		n /= 10;

	}
	return count;
}

int main()
{
	int count1,count2,digit;
	for ( digit = 1;digit < 101;digit++)
	{
		count1 = judge(digit);
		count2 = judge2(digit);
		int sum = 0;
		int m, n;
		for (int i = count2;i >= 1;i--)
		{
			m = digit %10;
			n = digit % count1;;
			digit /=10;
			count1 /= 10;
			sum += m * n;
			printf("%d", sum);
		}
		if (sum % count1 == digit)
		{
			printf("%d是自守数\n", digit);
		}

   }


}

上边是错的,调试出来再改

下边全函数重新写的版本

#include<stdio.h>
int JudgeSlj(int n)//判断数量级的函数
{
	int count =1;
	while (n != 0)
	{
		count *= 10;
		n /= 10;
	}
	return count;
}
int JudgeDigit(int n)
{
	int count = 0;
	while (n != 0)
	{
		count++;
		n /= 10;
	}
	return count;
}
int GetDigit(int n,int i)
{
	int remainder;
	int j = 0;
	int count = 1;
	while(j<i)
	{
		j++;
		remainder = n % 10;
		count *= 10;
		n /= 10;
	}
	remainder = remainder * count / 10;
	return remainder;

}
int GetLastOfDigit(int n, int i)
{
	int mul = 1;
	int j = 0;
	while (j <= i)
	{
		j++;
		mul *= 10;
	}
	return n % mul;
}

int main()
{
	int count1, count2, i, j, m, n;
	for (i = 1;i < 10000;i++)
	{
		count1 = JudgeSlj(i);
		count2 = JudgeDigit(i);
		int sum = 0;
		for (j = 1;j <= count2;j++)
		{
			m = GetDigit(i,j);
			n = GetLastOfDigit(i, count2 + 1 - j);
			sum += m * n;
		}

		if (sum % count1 == i)
		{
			printf("%d是自守数\n", i);
		}
	} 
}

虽然很长,但是很好懂;

例4.找出一个数的"子孙数";

在这里插入图片描述

#include<stdio.h>
int f[1010];
int recursion(int n)
{
	int i;
	if (f[n] != 0)
	{
		return f[n];
	}
	else
	{
		int s = 1;
		for (i = 1;i <=n / 2;i++)
		{
			s += recursion(i);
		}
		f[n] = s;
		printf("%d%d\n",n, f[n]);
		return f[n];
	}

}
int main()
{
	int i, j, n;
	scanf_s("%d", &n);
	f[1] = 1;
	int s = recursion(n);
	for (i = 1;i < 7;i++)
	{
		printf("%d", f[i]);
	}

}

递归思想:现在只能看懂,自己写还是写不出来,先记下来吧;

例5求水仙花数

秋水仙数,指的是一个三位数,各个位数的立方等于该数本身。
分析;获取各个位数,判断立方和是否为自身

#include<stdio.h>
int get(int n, int i)
{
	int j=1;
	int remainder;
	while (j <= i)
	{
		j++;
		remainder = n %  10;
		n /= 10;
	}
	return remainder;

}
int main()
{
	int n;
	int a, b, c;
	for (int i = 100;i < 1000;i++)
	{
		a = get(i, 1);
		b = get(i, 2);
		c = get(i, 3);
		if (a * a * a + b * b * b + c * c * c == i)
		{
			printf("%d\n", i);
		}

	}
}

到此关于有趣的数的集合已经写完,后期会总结,常用操作;就是各种切数字哈哈哈;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值