机试算法学习题(第二章 枚举和模拟问题)

本文介绍了C++编程中涉及枚举、循环、二维数组和字符串处理的一些常见问题和技巧,如计算日期、模拟打印图案和处理字符串等,并提供了相关代码示例和解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CSDN设置字体样式及颜色(附颜色表)

地址

2.1枚举 abc问题

OJ地址
描述
设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。
输入描述:
题目没有任何输入。
输出描述:
请输出所有满足题目条件的a、b、c的值。 a、b、c之间用空格隔开。 每个输出占一行。

思路:利用for循环遍历整个三位数

#include<cstdio>
using namespace std;
int main() {
   
   
	int a, b, c;
	for (a = 0; a <=9; a++){
   
   
		for (b = 0; b <=9; b++) {
   
   
			for (c = 0; c <=9; c++) {
   
   
				if (100 * a + 10 * b + c + 100 * b + 10 * c + c == 532) {
   
   
					printf("%d %d %d\n",a,b,c);//%d是占位符,打印一个整数用一个%d,打印3个整数就用3个%d,再用a b c填上
				}//d是decimal(十进制)的缩写
			
			}
		}
	}
}

2.2枚举 反序数

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

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

思路1
遍历整个4位数,四重循环暴力解,寻找符合条件的数值,注意排除0000

#include<iostream>
using namespace std;
int main() {
   
   
	int a, b, c, d;
	for (a = 0; a < 10; a++)
	{
   
   
		for (b = 0; b < 10; b++) {
   
   
			for (c = 0; c < 10; c++) {
   
   
				for (d = 0; d < 10; d++) {
   
   
					int temp = a * 1000 + b * 100 + c * 10 + d;
					if (temp!=0&&temp * 9 == d * 1000 + c * 100 + b * 10 + a) {
   
   
						cout << a << b << c << d << endl;
					}
				}
			}
		}
	}
}

思路二:利用remain变量保存每次循环所得到的的余数,利用reverse变量来求反序数。然后结合abcd四重循环 把求reverse的代码封装成一个函数。先写相对独立的模块,以便调试(增量编写法,写一个模块测试一个模块)

#include<cstdio>
int Reverse(int n) {
   
   
	int remain;//保存余数
	int reverse = 0;//反序数
	while (true)//第二种写法,只知道循环会进行且会跳出但不清楚循环边界时
	{
   
   
		remain = n % 10;
		n = n / 10;
		reverse = reverse * 10 + remain;
		//当最后一次循环执行时,退出循环
		if (n == 0) {
   
   
			break;
		}
		
	}
	return reverse;
}
int main(){
   
   
	int a, b, c, d;
	for (a = 0; a < 10; a++) {
   
   
		for (b = 0; b < 10; ++b)
		{
   
   
			for (c = 0; c < 10; c++) {
   
   
				for (d = 0; d < 10; d++) {
   
   
					int n = 1000 * a + 100 * b + 10 * c + d;
					if (n * 9 == Reverse(n)&&n!=0) {
   
   
						printf("%d\n", n);
					}
						
				}
			}
		}
	}
	/*while (n > 0) {//第一种写法
		remain = n % 10;
		n =n/ 10;
		reverse = reverse * 10+remain;
	}*/
	
}

2.3枚举 对称平方数

OJ链接
描述
打印所有不超过256,其平方具有对称性质的数。如2,11就是这样的数,因为22=4,1111=121。
输入描述:
无任何输入数据
输出描述:
输出具有题目要求的性质的数。如果输出数据不止一组,各组数据之间以回车隔开。

自己写的:利用2.2反序数的思想。判断平方之后得到的数据是否为一个反序数

#include<cstdio>
int Reverse(int n) {
   
   
	int remain, reverse;
	remain = 0;
	reverse = 0;
	while (n>0)
	{
   
   
		remain = n % 10;
		reverse = reverse * 10 + remain;
		n = n / 10;
	}
	return reverse;
}
int main() {
   
   
	/*int temp;
	temp = Reverse(11);
	printf("%d", temp);*/
	int i = 0;
	for (i = 0; i < 257; i++)
	{
   
   
		if (i * i == Reverse(i * i))
		{
   
   
			printf("%d\n", i);
		}
	}
}

PS:如果出现了死循环要检查一下任务管理器,检查CPU是否一直在转。
要检查循环的入口和break的地方是否无法执行

编程规范

1、使用==表达式,在左边写固定值

if(0==n)//写成0=n时编译器会报错,方便排查bug
{
   
   ……}

2、永远不要省略花括号

枚举练习一 与7无关的数

OJ地址
描述
一个正整数,如果它能被7整除,或者它的十进制表示法中某个位数上的数字为7, 则称其为与7相关的数.现求所有小于等于n(n<100)的与7无关的正整数的平方和。
输入描述:
案例可能有多组。对于每个测试案例输入为一行,正整数n,(n<100)
输出描述:
对于每个测试案例输出一行,输出小于等于n的与7无关的正整数的平方和。
示例1
输入: 21
输出:2336

自己写的代码如下:
注意判断十进制表示法中某个位数上的数字为7上时,要排除0%7的情况

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
int func(int n) {
   
   
	int temp = n;
	int remain = 0;
	while (temp)
	{
   
   
		remain = temp % 10;
		if (remain!=0&&remain % 7 == 0)//如果temp=10也会导致remian为0,不符合题意,所以要加上remian!=0
		{
   
   
			return 0;
		}
		temp = temp / 10;
	}
	if (0 == n % 7) {
   
   
		return 0;
	}
	return n * n;
		
	
}
int main() {
   
   
	int n, sum;
	cin >> n;
	sum = 0;
	if (n < 100) {
   
   
		for (int i = 1; i <= n; i++)
			sum = sum + func(i);

	}
	else
	{
   
   
		cout << "请重新输入" << endl;
	}
	cout << sum;
}

其他人的答案

#include<iostream>
 
using namespace std;
 
bool isRelative(int num){
   
   
    if(num % 7 == 0) return false;
    while(num){
   
   
        if(num % 10 == 7) return false;
        num /= 10;
    }
    return true;
}
int main(){
   
   
    int n;
    while(cin >> n){
   
   
        int sum = 0;
        for(int i = 1; i <= n; i ++){
   
   
            if(isRelative(i))
                sum += i * i;
        }
        cout << sum << endl;
    }
}

枚举练习二:百鸡问题

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

输入描述:
测试数据有多组,输入n。
输出描述:
对于每组输入,请输出x,y,z所有可行解,按照x,y,z依次增大的顺序输出。
示例1
输入:
40
输出:
x=0,y=0,z=100
x=0,y=1,z=99
x=0,y=2,z=98
x=1,y=0,z=99

自己的解法

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;

int main() {
   
   
	int i, n, x, y, z;
	cin >> n;
	for (x = 0; x <=100; x++) {
   
   
		for (y = 0; y <=100; y++) {
   
   
			for (z = 0; z <= 100; z++)
			{
   
   
				if ((100 == x + y + z) && (5*x + 3*y + (1.0/3)*z <=n)) {
   
   
					cout << "x=" << x << "," << "y=" << y << "," << "z=" << z << endl;
				}
			}
		}
	}
}

别人的解法

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;

int main() {
   
   
	int i, n, x, y, z;
	cin >> n;
	for (x = 0; x <=100; x++) {
   
   
		for (y = 0; y <=100; y++) {
   
   
			for (z = 0; z <= 100; z++)
			{
   
   
				if ((100 == x + y + z) && (5*x + 3*y + (1.0/3)*z <=n)) {
   
   
					cout << "x=" << x << "," << "y=" << y << "," << "z=" << z << endl;
				}
			}
		}
	}
}

枚举练习三 Old Bill

OJ地址
描述
Among grandfather’s papers a bill was found. 72 turkeys $679 The first and the last digits of the number that obviously represented the total price of those turkeys are replaced here by blanks (denoted _), for they are faded and are illegible. What are the two faded digits and what was the price of one turkey? We want to write a program that solves a general versi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值