本文主要是介绍“至少出现一次7”的数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
(本来是列为转载的,但是原文算法那里有不可原谅的错误,愤慨之下,收归己有)
给定一个正整数n,写一个算法计算从1到n之间有多少“至少出现一次7”的数。例如n=20,那么有两个出现7的数:7,17。
算法
去掉个位的数字有N/10个,这也是个位为7的数的个数,包含出现多于一个7的情况,以下类推
再去掉十位的数字有N/100个,乘以9是十位为7的数的个数(个位不能再取7,所以乘9)
再去掉百位的数字有N/1000个,乘以81是百位为7的数的个数(个位或十位都不能再取7,所以乘9的平方)
依次类推。。。对于个位大于等于7的数字,最后的结果还要+1
例如2000内有7的个数=200+20*9+2*81=542, 2000/10 = 200 是个位出现7的数的个数,2000/200×9是十位出现7的情况,2000/1000×9×9是百位出现7的情况,个位小于7,不需要额外加1。
进一步解释:以2000作为例子,考虑个位为7的情况,从07,17,27一直到1997,个位为7的情况出现了200次(0到199); 考虑十位为7的情况,07x,17x,27x一直到197x,其中x代表除了7外的其他数字,所以十位为7的情况为20次(0到19)乘以9(个位的情况), 由于排除了个位是7的情况,所以不会跟第一种情况算重; 考虑百位为7的情况,07xx,17xx,所以百位为7的情况事2乘以9的平方。
为什么个位数大于等于7的话还要额外+1?譬如2018,因为2017事实上没有算入之前的几种情况,只算了(0到200).
这么一分析的话,代码就很简单了:
#include <iostream>
#include <cmath>
using namespace std;int get7num(int n) {int p = 0;int num = 0;int bonus = (n%10 >= 7);while(n != 0) {num += (n/10)*pow(9,p);p++;n /= 10;}return num + bonus;
}int main() {cout << get7num(2007) << endl;return 0;
}
这篇关于“至少出现一次7”的数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!