用C++写洛谷P1590失踪的7

这篇博客探讨了古代Pascal人的计数系统,他们避免使用数字7,将8视为7,18视为16。文章提供了两个解决方法来计算在正整数n范围内不包含数字7的Pascal数字的数量。第一个方法通过数字转字符串检查每位是否为7,第二个方法利用九进制转换实现。博客提供了两种解决方案的代码实现,并展示了它们如何处理大数值的情况。
摘要由CSDN通过智能技术生成

题目描述

远古的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 循环的控制流:

  1. init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
  2. 接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
  3. 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
  4. 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,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;
} 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值