59
社区成员




小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int ans = 0, x;
for (int i = 1; i <= 2020; i++)
{
x = i;
while (x)
{
________________;
}
}
cout << ans;
return 0;
}
提示:
利用循环将当前数字的每一位求出,分别进行判断即可
0-9有1个数为2,有9个数不为2。所含2的个数a(1)=1
以此进行递推:
0-99 所含2的个数记为a(2)
最高位不为2的时候,所有这样的数所含的2的个数为9a(1)
最高位为2的时候一共有10个数含有2只是个数暂时不明(20-29),但我们可以确定保底有10个2,因为这10个数是20多。现在思考难道只有10个2?显然不是,因为只算了最高位,故少算了a(1)个2。所以a(2)=9a(1)+101+a(1)=10a(1)+101
现在考虑0-999 所含2的个数记为a(3)
同理,最高位不为2的时候,所有这样的数所含的2的个数为9a(2)
最高位为2的时候一共有100个数(200-299),但我们可以确定保底有100个2,因为这100个数是200多。现在思考难道只有10个2?显然不是,因为只算了最高位,最高位以后都没计算,故少算了a(2)个2。所以a(3)=9a(2)+10^21+a(2)=10a(2)+10^21
归纳法可得0-99...99(n个9) 所含2的个数a(n)=10a(n-1)+10^(n-1)
本题求0-2020,先拆分成0-1999,2000-2020.
0-1999:由前面递推0-999含有2的个数a(3)=300,最高位0,1都不是2,所以0-1999有2a(3)=600个2
2000-2020:由于最高位为2,这21个数保底有21个2。因为只算了最高位,最高位以后都没计算,故少算了0-20(含有3个2)
综上600+21+3=624
画个思维重点:0-9之前,出现一个2,透过循环算进位,从而结合起来计算一堆数据的2有几个。
短除法,基本功
判断x%2 == 2 是求个位是否为2,如果是就让计数器+1,然后令x=x/2是为了求比一个位更高的一位让其又成为个位,然后一直循环判断,直到最后统计完成
let ans = 0;
for (let i = 1; i <= 2020; i++) {
let x = i;
while (x) {
if (x % 10 === 2) {
ans++;
}
x = Math.floor(x / 10);
}
}
console.log(ans);
我们使用 while 循环来逐位判断数字 2 的出现次数。我们使用取模运算符 % 来判断个位数是否为数字 2,如果是,则将 ans 的计数加一。然后,我们将 x 除以 10,去掉个位数,继续判断下一位数。最后,通过循环计算出数字 2 出现的次数,并将结果输出。
门牌号包括2的,例如 2,12,22,32----1002,1020
计算开始:
个位:例如门牌2:2%10=2
十位:例如门牌12:个位计算12%10=2,进一位计算(取整数)12/10=1,判断1%10不等于2,不满足if条件,进一位计算(取整)1/10=0,不满足while条件,循环结束
百位: 例如门牌122:照例个位计算,进一位计算,取当前(十位)余数,接着进位计算......
按进制取余思路主要计算步骤 1:当前位如何取到2;2:如何进到下一位计算
count = 0
for i in range(0,2001):
if str(2) in str(i):
count += 1
print(count)
let arr = [],obj = Object.create(null)
for (let i = 1; i <= 2020; i++){
i > 9 ? arr = arr.concat((i+'').split('')) : arr.push(i+'')
}
for(let i = 0; i <= 9; i++){
for(let j = 0; j < arr.length; j++) {
if (i == arr[j]) {
obj[i+''] ? obj[i] += 1 : obj[i+''] = 1
}
}
}
console.log('obj----->', obj)
输出:
obj-----> {0: 523, 1: 1612, 2: 624, 3: 602, 4: 602, 5: 602, 6: 602, 7: 602, 8: 602, 9: 602}
取余,整除
#include<stdio.h>
int main()
{
int ans = 0, x;
for(int i = 1; i <= 2020; i++)
{
x = i;
while(x)
{
if(x % 10 == 2)
{
ans++;
}
x /= 10;
}
}
printf("%d", ans);
return 0;
}
```java
package Primary;
public class MenpaiZhizuo {
public static void main(String args[]) {
int count=0;//计数变量
//循环遍历
for(int i=1;i<=2020;i++) {
do {
if(i%10==2) {
count++;
}i/=10;
}while(i!=0);
}
System.out.println(count);
}
}
```
#include"stdio.h"
main(void){
int cnt = 0;
for(int i = 1;i <= 2020;i++){
int j = i;
while(j){
if(j % 10 == 2){
cnt++;
}j /= 10;
}
}printf("%d",cnt); // 结果为624
return 0;
}
有没有用c语言的
虽然有点笨拙,但比较好理解。
let count = 0;
for (let i = 1; i <= 2020; i++) {
let x = i;
//个位符合的x, 并摘掉个位的2 = 符合的个数;
if (x % 10 == 2) {
x -= 2;
// console.log(x);
count++;
}
//十位符合的x, 并摘掉十位的2 = 符合的个数;
if (parseInt(x / 10) % 10 == 2) {
x -= 20;
// console.log(x);
count++;
}
//百位符合的x, 并摘掉百位的2 = 符合的个数;
if (parseInt(x / 100) % 10 == 2) {
x -= 200;
// console.log(x);
count++;
}
//千位符合的x, 并摘掉千位的2 = 符合的个数;
if (parseInt(x / 1000) % 10 == 2) {
x -= 2000;
// console.log(x);
count++;
}
}
console.log('符合个数:' + count);
//结果624
主页或者专栏有助于学习高效C语言 https://blog.csdn.net/gzplyx?type=blog
Console.WriteLine("门牌制作");
int ans = 0, x;
for (int i = 1; i <= 2020; i++)
{
x = i;
while (x != 0)
{
if (x % 10 == 2) ans++;
x /= 10;
}
}
Console.WriteLine(ans);
Console.ReadLine();