列表

详情


NC231395. [NOIP2021]报数(number)

描述

    报数游戏是一个广为流传的休闲小游戏。参加游戏的每个人要按一定顺序轮流报数,但如果下一个报的数是 7 的倍数,或十进制表示中含有数字 7 ,就必须跳过这个数, 否则就输掉了游戏。

    在一个风和日丽的下午,刚刚结束SPC20nn比赛的小 r 和小 z 闲得无聊玩起了这个报数游戏。但在只有两个人玩的情况下计算起来还是比较容易的,因此他们玩了很久   也没分出胜负。此时小 z 灵光一闪,决定把这个游戏加强:任何一个十进制中含有数字 7 的数,它的所有倍数都不能报出来!

    形式化地,设 p(x) 表示 x 的十进制表示中是否含有数字 7 ,若含有则 , 否则 。则一个正整数 x 不能被报出,当且仅当存在正整数 y 和 z ,使得  且  。

    例如,如果小 r 报出了 6 ,由于 7 不能报,所以小 z 下一个需要报 8 ;如果小 r 报出了 33 ,则由于   都不能报,小 z 下一个需要报出 36 ;如果小 r 报出了 69 ,由于  的数都含有 7 ,小 z 下一个需要报出 80 才行。

    现在小 r 的上一个数报出了 x,小 z 想快速算出他下一个数要报多少,不过他很快就发现这个游戏可比原版的游戏难算多了,于是他需要你的帮助。当然,如果小 r 报出的 x 本身是不能报出的,你也要快速反应过来小 r 输了才行。

    由于小 r 和小 z 玩了很长时间游戏,你也需要回答小 z 的很多个问题。

输入描述

第 1 行,一个正整数 T 表示小 z 询问的数量。

接下来 T 行,每行 1 个正整数 x,表示这一次小 r 报出的数。

输出描述

输出共 T 行,每行一个整数,如果小 r 这一次报出的数是不能报出的,输出  , 否则输出小 z 下一次报出的数是多少。

示例1

输入:

4
6
33
69
300

输出:

8
36
80
-1

说明:

这一组样例的前 3次询问在题目描述中已有解释。

对于第 4 次询问,由于 300 = 75×4,而 75 中含有 7 ,所以小 r 直接输掉了游戏。

示例2

输入:

5
90
99
106
114
169

输出:

92
100
109
-1
180

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 563ms, 内存消耗: 43888K, 提交时间: 2023-07-31 17:03:11

#include<bits/stdc++.h>
using namespace std;
const int maxn=10001000;
int cnt,t,x;
int vis[maxn],lis[maxn];
bool check(int x)
{
	while(x)
	{
		if(x%10==7)
		{
			return 0;
		}
		x/=10;
	}
	return 1;
}
void init()
{
	for(int i=1;i<=maxn;i++)
	{
		if(vis[i]==0)
		{
			if(check(i))
			{
				vis[i]=++cnt;
				lis[cnt]=i;
			}
			else
			{
				for(int j=1;i*j<=maxn;j++)
				{
					vis[i*j]=-1;
				}
			}
		}
	}
}
int main()
{
	cin>>t;
	init();
	while(t--)
	{
		cin>>x;
		if(vis[x]==-1)
		{
			cout<<"-1"<<endl;
		}
		else
		{
			cout<<lis[vis[x]+1]<<endl;
		}
	}
	return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 661ms, 内存消耗: 72756K, 提交时间: 2022-10-15 10:36:38

#include<bits/stdc++.h>
using namespace std;
int is[10000005],nex[10000005],st[10000005],sum,t;
int main(){
    scanf("%d",&t);
	for(int i=1;i<=10000001;++i){
		if(is[i])continue;
		if(to_string(i).find('7')==-1){
			st[++sum]=i,nex[i]=sum;
			continue;
		}
		for(int j=i;j<=10000001;j+=i)is[j]=1;
	}
	while(t--){
		int x;
		scanf("%d",&x);
		if(!is[x])printf("%d\n",st[nex[x]+1]);
		else printf("-1\n");
	}
}

上一题