题目描述
远古的Pascal人也使用阿拉伯数字来进行计数,但是他们又不喜欢使用7,因为他们认为7是一个不吉祥的数字,所以Pascal数字8其实表示的是自然数中的7,18表示的是自然数中的16。下面计算一下,在正整数n范围以内包含有多少个Pascal数字。
输入格式
第一行为正整数t,接下来t行,每行一个正整数n(≤2^32-1)。
输入的是Pascal数字
t≤10000
输出格式
对于每个正整数n,输出n以内的Pascal数的个数。
输入输出样例
输入 #1复制
2 10 20
输出 #1复制
9 18
以下提供俩种思路(第二种可以AC):
第一次写题思路:
从0到n个数遍历,取每个数的每一位数(个、十、百、千、万等)出来判断有没有‘7’,如果有就不计数。这样的方法可以用数字转字符串来写。算法没有问题,但是对于太大的数据就无能为力了。数据换为long long类型还是不能AC,如果知道解决办法的感谢告知。
第一次代码如下:
#include <iostream>
#include <sstream>
//这个算法没问题,但是数据太大就不行了
using namespace std;
int main(){
int a,t,n=0;
cin >> t;
int k=t;
int x[t];
string s,s0;
while(t>0){
cin >> s;
stringstream ss;
ss << s;
ss >> a;//cout <<"a:"<< a << "。"<< endl;
for(int j = 1;j <= a;j++){
n++;
stringstream sss;
sss << j;
sss >> s0;//cout << "s0:"<< s0<<"。"<<endl;
for(int i = 1;i <= s0.length();i++){
if(s0[i-1]=='7'){
n--;
break;
}
}
}
x[t]=n;
n=0;
t--;
}
while (k>0){
cout << x[k] << endl;
k--;
}
return 0;
}
第二次写题思路:
换另一种方法,采用特判7的九进制转换十进制来写。
其中需要补充几点知识点:
(1)C++杂项运算符:
Condition ? X : Y | 条件运算符。如果 Condition 为真 ? 则值为 X : 否则值为 Y。 |
(2) C++ 中 for 循环的语法:
for ( init; condition; increment ) { statement(s); }
for 循环的控制流:
- init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
- 接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
- 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
- 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。
其中condition位置填一个变量的意思是:
C语言中0是假,所以n就是n!=0,类似的if(n)等价于if(n!=0),if(!n)等价于if(n==0)
第二次AC代码如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
long long time,n,end,s;
cin >> time;int t=time,a[t];
while(t--){
for(s=1,end=0,cin >> n;n!=0;n/=10,s*=9){
end+=s*(n%10)-(n%10>=7?s:0);
}
a[t]=end;
}
while(time--){
cout << a[time] << endl;
}
return 0;
}