本文由荒原之梦原创,原文链接:http://zhaokaifeng.com/?p=1475
题目
奖券数目
有些人很迷信数字,比如带“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