《算法笔记》5.1小节——数学问题->简单数学

PAT B1019 数字黑洞
问题描述:给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767开始,将得到

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...

现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。

  • 输入
输入给出一个 (0,10 4 ) 区间内的正整数 N。
  • 输出
如果 N 的 4 位数字全相等,则在一行内输出 N - N = 0000;否则将计算的每一步在一行内输出,直到 6174 作为差出现,输出格式见样例。注意每个数字按 4 位数格式输出。
  • 样例输入1
6767
  • 样例输出1
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
  • 样例输入2

2222

 - 样例输出2
 ```cpp
2222 - 2222 = 0000

注意为0时的判断,数组array和数字num之间的转换。

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
bool cmp(int a, int b)
{
	return a > b;
}
int to_number(int a[])
{
	int i;
	int temp = 1; 
	int ans=0;
	for (i = 3; i >=0; i--)
	{
		ans += a[i] * temp;
		temp *= 10;
	}
	return ans;
}
void to_array(int a[],int temp)
{
	int i;
	for (i = 0; i <4; i++)
	{
		a[i] = temp % 10;
		temp /= 10;
	}
	return;
}
int main()
{
	int i;
	
	int a[5];
	int num;
	int num1, num2;
	int temp=0;//当前两个数的差值
	
	scanf("%d", &num);//从输入获取数字
	

	while (1)
	{		
		to_array(a,num);//将数字存储到整数数组a内
		sort(a, a + 4);//从小到大排列
		num1 = to_number(a);//输出到num1中
		sort(a, a + 4, cmp);//
		num2 = to_number(a);
		num = num2 - num1;//计算大数建去小数
		printf("%04d - %04d = %04d\n", num2, num1,num);
		if (num == 0||(num==6174))
			break;		
	}
	return 0;
}

问题 A: 守形数
问题描述:守形数是这样一种整数,它的平方的低位部分等于它本身。
比如25的平方是625,低位部分是25,因此25是一个守形数。
编一个程序,判断N是否为守形数。

  • 输入
输入包括1个整数N,2<=N<100
  • 输出
可能有多组测试数据,对于每组数据,
输出"Yes!”表示N是守形数。
输出"No!”表示N不是守形数。
  • 样例输入
6
11
  • 样例输出
Yes!
No!

基础题

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
	int N;
	int N2;
	int flag;
	int temp;
	while (scanf("%d",&N)!=EOF)
	{
		N2 = N * N;
		flag = 1;
		temp = N2 - N;
		while (N != 0)
		{
			flag*=10;
			N /= 10;
		}
		if (temp%flag == 0)
			printf("Yes!\n");
		else
			printf("No!\n");
	}

	return 0;
}

问题 B: 反序数
问题描述:设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321)
求N的值

  • 输入
程序无任何输入数据
  • 输出
输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开。

注意在循环里的数不能变化,所以把num1存放在了temp里面。

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
	int num1;
	int num2;
	int i;
	int a[4]; int b[4];
	int temp;
	for (num1 = 1000; num1 < 1111; num1++)
	{	
		num2 = num1 * 9;
		temp = num1;//因为num1是循环变量,所以要注意将它的值存在别的变量里
		for (i = 0; i < 4; i++)
		{
			a[i] = temp % 10;
			b[i] = num2 % 10;
			temp /= 10;
			num2 /= 10;
		}
		if ((a[0]==b[3]) && (a[1]==b[2]) && (a[2]==b[1]) && (a[3]==b[0]))
		{
			printf("%d\n",num1);
		}
	}
	return 0;
}

问题 C: 百鸡问题
问题描述:用小于等于n元去买100只鸡,大鸡5元/只,小鸡3元/只,还有1/3元每只的一种小鸡,分别记为x只,y只,z只。编程求解x,y,z所有可能解。

  • 输入
测试数据有多组,输入n。
  • 输出
对于每组输入,请输出x,y,z所有可行解,按照x,y,z依次增大的顺序输出。
  • 样例输入
45
  • 样例输出
x=0,y=0,z=100
x=0,y=1,z=99
x=0,y=2,z=98
x=0,y=3,z=97
x=0,y=4,z=96
x=1,y=0,z=99
x=1,y=1,z=98
x=1,y=2,z=97
x=2,y=0,z=98

基础题

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
int main()
{
	int x, y, z, n;
	int sum;
	while (scanf("%d", &n) != EOF)
	{
		for (x = 0; x <= n / 5; x++)
			for(y=0;y<=(n-5*x)/3;y++)
				for (z = 0; z <=3*(n-5*x-3*y); z++)
				{
					sum = x + y + z;//总的鸡个数
					if (sum == 100)
						printf("x=%d,y=%d,z=%d\n",x,y,z);
				}
		{
		}
	}
	return 0;
}

问题 D: abc
问题描述:设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。

  • 输入
题目没有任何输入。
  • 输出
请输出所有满足题目条件的a、b、c的值。
a、b、c之间用空格隔开。
每个输出占一行。

这题通过数学推导就行了,我直接输出了321(狗头)

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
using namespace std;
int main()
{
	printf("3 2 1\n");
	return 0;
}

问题 E: 众数
问题描述:输入20个数,每个数都在1-10之间,求1-10中的众数(众数就是出现次数最多的数,如果存在一样多次数的众数,则输出权值较小的那一个)

  • 输入
测试数据有多组,每组输入201-10之间的数。
  • 输出
对于每组输入,请输出1-10中的众数。
注意如果存在一样多次数的众数,则输出权值较小的那一个。
  • 样例输入
8 9 6 4 6 3 10 4 7 4 2 9 1 6 5 6 2 2 3 8
  • 样例输出
6

这题注意不能用while(1)循环,这样会报黄错,输出超限

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
	int a[25] = {0};
	int temp;
	while (scanf("%d", &temp)!=EOF)
	{
		a[temp]++;
		for (int i = 2; i <= 20; i++)
		{
			scanf("%d", &temp);
			a[temp]++;
			
		}
		int max = 1;
		for (int i = 2; i <= 10; i++)
		{
			if (a[i] > a[max])
				max = i;
		}
		printf("%d\n", max);
		memset(a, 0, sizeof(a));
	}
	
}

问题 F: 计算两个矩阵的乘积
问题描述:计算两个矩阵的乘积,第一个是23矩阵,第二个是32矩阵,结果为一个2*2矩阵。

  • 输入
在这里插入代码片
  • 输出
在这里插入代码片
  • 样例输入
在这里插入代码片
  • 样例输出
在这里插入代码片

注意三个循环计算矩阵乘积

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
	int a[2][3], b[3][2], c[2][2];
	int i, j,m,n;
	while (scanf("%d", &a[0][0]) != EOF)
	{
		scanf("%d %d",&a[0][1],&a[0][2]);
		scanf("%d %d %d", &a[1][0], &a[1][1],&a[1][2]);
		scanf("%d %d %d %d %d %d", &b[0][0], &b[0][1], &b[1][0],&b[1][1],&b[2][0],&b[2][1]);
		for (m = 0; m < 2; m++)
			for (n = 0; n < 2; n++)
				c[m][n] = 0;
		for (m = 0; m < 2; m++)
		{
			for (n = 0; n < 2; n++)
			{
				for (i = 0; i < 3; i++)					
					c[m][n] += a[m][i] * b[i][n];					
				printf("%d", c[m][n]);
				if (n != 1)
					printf(" ");
			}
			printf("\n");
		}			
	}	
}

问题 K: 迭代求立方根
问题描述:立方根的逼近迭代方程是 y(n+1) = y(n)2/3 + x/(3y(n)*y(n)),其中y0=x.求给定的x经过n次迭代后立方根的值。

  • 输入
输入有多组数据。
每组一行,输入x n。
  • 输出
迭代n次后的立方根,double精度,保留小数点后面六位。
  • 样例输入
4654684 1
65461 23
  • 样例输出
3103122.666667
40.302088

这题注意输入的x可能是double,不需要用longlong存储,要小心越界的情况

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
	double x;
	int n;
	int i;
	double temp;
	while (scanf("%lf %d", &x, &n) != EOF)
	{
		temp = x;
		for (i = 0; i < n; i++)
		{
			x = (x / 3) * 2 + temp / 3 / x / x;
		}
		printf("%.6f\n",x);
	}			
	return 0;	
}

问题 M: 鸡兔同笼
问题描述:
一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。

  • 输入
1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,每行一个正整数a (a < 32768)
  • 输出
输出包含n行,每行对应一个输入,包含两个正整数,第一个是最少的动物数,第二个是最多的动物数,两个正整数用一个空格分开
如果没有满足要求的答案,则输出两个0
  • 样例输入
2
18
5
  • 样例输出
5 9
0 0

基础题,分类讨论即可

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
	int a;
	int max, min;
	int i, N;
	scanf("%d", &N);
	for (i = 0; i < N; i++)
	{
		scanf("%d", &a);
		if (a % 2 != 0)
			min = max = 0;
		else if (a % 4 == 0)//a是4的倍数
		{
			min = a / 4;
			max = a / 2;
		}
		else//a是2的倍数,但不是4的倍数
		{
			min = a / 4 + 1;
			max = a / 2;
		}
		printf("%d %d\n", min, max);
	}	
	return 0;	
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值