AtCoder题解 —— AtCoder Beginner Contest 186 —— C - Unlucky 7 —— 模拟算法

题目相关

题目链接

AtCoder Beginner Contest 186 C 题,https://atcoder.jp/contests/abc186/tasks/abc186_c。

Problem Statement

Takahashi hates the number 7.
We are interested in integers without the digit 7 in both decimal and octal. How many such integers are there between 1 and N (inclusive)?

Input

Input is given from Standard Input in the following format:

N

Output

Print an integer representing the answer.

Sample 1

Sample Input 1

20

Sample Output 1

17

Explaination

Among the integers between 1 and 20, 7 and 17 contain the digit 7 in decimal. Additionally, 7 and 15 contain the digit 7 in octal.
Thus, the 17 integers other than 7, 15, and 17 meet the requirement.

Sample 2

Sample Input 2

100000

Sample Output 2

30555

Constraints

  • 1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^{5} 1N105
  • N is an integer.

题解报告

题目翻译

高桥讨厌数字 7。请告诉我们从 [ 1 , n ] [1, n] [1,n] 之间,有几个数组不包含数字 7,不管是十进制还是八进制。

题目分析

本次的 C 题比较简单,一个非常普通的模拟题。我们只需要从 1 到 N 之间统计一下,不管十进制还是八进制数字 i 包含 7 的个数 ans,最终答案为 n − a n s n-ans nans

如何判定包含数字 7

最简单的方法是转化称为 string,然后利用 find 函数。

将数字转化称为十进制字符串

我们可以使用 sprintf 函数,只需要使用参数 %d 即可完成。代码类似如下:

sprintf(buf, "%d", i);

将数字转化称为八进制字符串

我们可以使用 sprintf 函数,只需要使用参数 %o 即可完成。代码类似如下:

sprintf(buf, "%o", i);

数据范围估计

根据题目,最大的 N N N 1 0 5 10^5 105,因此用 int 也就够了。

AC 参考代码

//https://atcoder.jp/contests/abc186/tasks/abc186_c
//C - Unlucky 7
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
 
//#define __LOCAL
 
int main() {
    
    
#if !defined(__LOCAL)
    cin.tie(0);
    ios::sync_with_stdio(false);
#endif
    int n;
    cin>>n;
 
    char buf[10];
    int ans = 0;
    for (int i=1; i<=n; i++) {
    
    
        //十进制
        sprintf(buf, "%d", i);
        string s=string(buf);
        if (string::npos != s.find('7', 0)) {
    
    
            ans++;
        } else {
    
    
            //二进制
            sprintf(buf, "%o", i);
            s=string(buf);
            if (string::npos != s.find('7', 0)) {
    
    
                ans++;
            }
        }
    }
    cout<<n-ans<<"\n";
 
    return 0;
}

在这里插入图片描述

时间复杂度

O(N)。

空间复杂度

O(1)。

另外一个思路

上面我们采用比较笨的方法,也就是将每个数字转换称为对应的十进制和八进制,然后再判断是否包含 7。其实,我们完全可以根据数学定义,对本题进行优化。

十进制数包含 7

对于一个十进制,包含 7。我们只需要对每一位进行判断是否包含数字 7,这样问题就变为遍历 x 的每一位,判断是否含有数字 7。

bool judge1(int x) {
    
    
	while (x) {
    
    
		if (7==x%10) {
    
    
			//包含7
			return true;
		}
		x /= 10;
	}
	return false;
}

八进制数包含 7

同理,对于八进制而言,是否包含 7。也是判断每位是否含有 7,我们不需要将十进制转换为 8 进制,只需要对 8 取余即可。

bool judge2(int x) {
    
    
	while (x) {
    
    
		if (7==x%8) {
    
    
			//包含7
			return true;
		}
		x /= 8;
	}
	return false;
}

AC 参考代码

//https://atcoder.jp/contests/abc186/tasks/abc186_c
//C - Unlucky 7
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
 
//#define __LOCAL

bool judge(int x) {
    
    
	int t=x;
	//十进制判断
	while (x) {
    
    
		if (7==x%10) {
    
    
			//包含7
			return true;
		}
		x /= 10;
	}
	//八进制判断
	x=t;
	while (x) {
    
    
		if (7==x%8) {
    
    
			//包含7
			return true;
		}
		x /= 8;
	}
	return false;
}
 
int main() {
    
    
#if !defined(__LOCAL)
    cin.tie(0);
    ios::sync_with_stdio(false);
#endif
    int n;
    cin>>n;
 
    char buf[10];
    int ans = 0;
    for (int i=1; i<=n; i++) {
    
    
    	if (false==judge(i)) {
    
    
    		ans++;
    	}
    }
    cout<<ans<<"\n";
 
    return 0;
}

在这里插入图片描述

时间复杂度

O(N)。

空间复杂度

O(1)。

猜你喜欢

转载自blog.csdn.net/justidle/article/details/111411516