题目相关
题目链接
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} 1≤N≤105
- N is an integer.
题解报告
题目翻译
高桥讨厌数字 7。请告诉我们从 [ 1 , n ] [1, n] [1,n] 之间,有几个数组不包含数字 7,不管是十进制还是八进制。
题目分析
本次的 C 题比较简单,一个非常普通的模拟题。我们只需要从 1 到 N 之间统计一下,不管十进制还是八进制数字 i 包含 7 的个数 ans,最终答案为 n − a n s n-ans n−ans。
如何判定包含数字 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)。