2015 年蓝桥杯 C 语言 B 组省赛第 1 题: 奖券数目 (四种解法 + 详细分析)

题目

奖券数目

有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。 虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。

请提交该数字(一个整数),不要写任何多余的内容或说明性文字。

题目分析

本题的主要解题思路就是枚举 10000-99999 之间的所有数字, 然后判断其中是否含有 4 , 如果不含有 4 则计数器加 1.

在具体实现上, 有四种解法. 第一种解法是对每个枚举结果都进行分解, 将原来的 5 位数分解成 5 个 1 位数, 之后逐个数字判断是否含有数字 4; 第二种方法是把每个枚举的结果都转换成字符串, 之后判断这个字符串中是否包含字符”4″, 如果不包含则计数器加 1; 第三种解法是使用 5 个 for 循环, 模拟奖券的五位数, 之后进行枚举和判断; 第四种解法是使用数学方法求解. 由于除了数字 4 之外, 一共有 9 个数字可以使用, 而且最高位不能为 0, 那么可以计算出符合条件的个数为:

8*9*9*9*9=52488

本题的正确答案是:

52488

下面针对上述分析, 分别求解如下.

方法一

将 10000-99999 之间的所有 5 位数都逐个分解成 5 个 1 位数, 之后逐个数字判断是否为数字 4.

程序:

#include<iostream>
using namespace std;
int main(){
	int ans = 0;
	for(int i=10000;i<=99999;i++){
		
		//将每一位上的数字都分离出来
		//(i%1000) 取余将去掉当前最高位后形成新的数字
		//(i%10000)-(i%1000) 将把当前最高位之后的数字都变成 0
		//((i%10000)-(i%1000))/1000 将去掉最高位后面的 0, 形成一个个位数 
		int a = (i-(i%10000))/10000;	
		int b = ((i%10000)-(i%1000))/1000;
		int c = ((i%1000)-(i%100))/100;
		int d = ((i%100)-(i%10))/10;
		int e = (i%10);
		
		//如果每个位上的数字都不是 4 则计数器加 1 
		if(a!=4&&b!=4&&c!=4&&d!=4&&e!=4){
			ans++;
		}		
	}
	cout<<ans<<endl;
	return 0;
}

方法二

把 10000-99999 之间的每个枚举的结果都转换成字符串, 之后判断这个字符串中是否包含字符”4″.

程序:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
void i2s(int num, string &str){
//stringstream 类的作用是将数字转换成字符串
		stringstream ss;

//将需要转换的数字 sum 使用 << 运算符传递给 ss 对象 
		ss << num;
		
//将转换后的字符串使用 >> 运算符传递给 str 变量 
		ss >> str;
	}
int main(){
	int ans=0;
	for(int i=10000;i<=99999;i++){
		string s;
		i2s(i,s);
		
//查找字符串 s 中是否不包含(注意: 不包含用的是 ==)'4'这个字符串 
		if(s.find('4')==string::npos){
			ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

方法三

使用 5 个 for 循环, 模拟奖券的五位数, 之后进行枚举和判断. 程序:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
	int ans=0;
	for(int a=1;a<=9;a++){
		if(a!=4){
			for(int b=0;b<=9;b++){
				if(b!=4){
					for(int c=0;c<=9;c++){
						if(c!=4){
							for(int d=0;d<=9;d++){
								if(d!=4){
									for(int e=0;e<=9;e++){
										if(e!=4){
											ans++;
										}
									}
								}
							}
						}
					}
				}
			}
		}

	}
	cout<<ans<<endl;
	return 0;
}

方法四

由于除了数字 4 之外, 一共有 9 个数字可以使用, 而且最高位不能为 0, 那么可以计算出符合条件的奖券个数为:

8*9*9*9*9=52488