[NOIP2021] 报数


洛谷题面

题目大意

如果一个数 \(x\) 满足:为 \(7\) 的倍数或 \(x\) 的数字中含有 \(7\)\(f(x)=1\);反之则 \(f(x)=0\)

给定 \(T\) 组数据,对于每组数据:

给定一个正整数 \(n\),如果 \(a\times k=n(a,k\) \(\texttt{均为正整数且}\) \(f(a)=1\) \()\),则输出 \(-1\)

否则,找出第一个严格大于 \(n\) 的数 \(p\) 满足 \(f(r)=0(r\) \(\texttt{为 p 的因数}\) \()\) \(\texttt{且}\) \(r\times k=p\)

题目分析

考试的时候直接降智,这就是个裸的变种筛数。思考 \(10~min\) 没有思路,只打了暴力分。

\(70\) 分部分

思路

对于每个询问,在线回答。

直接暴力判断大于 \(n\) 的数字中是否含有不符合条件的因数。

如果找到了满足条件的,直接输出即可。

民间数据 \(70\) 分。

代码

还是给个吧。

int T,n;

inline bool chk(int x)
{
	while(x!=0)
	{
		if(x%10==7)
		{
			return true;
		}
		
		x/=10;
	}
	
	return false;
}

inline bool solve(int x)
{
	for(register int i=1;i*i<=x;i++)
	{
		if(x%i==0)
		{
			if(chk(i)==true || chk(x/i)==true)
			{
				return true;
			}
		}
	}
	
	return false;
}

int main(void)
{
	T=read();
	
	while(T--)
	{
		n=read();
		
		if(solve(n)==true)
		{
			puts("-1");
			
			continue;
		}
		
		for(n=n+1;;n++)
		{
			if(chk(n)==false && solve(n)==false)
			{
				break;
			} 
		}
		
		printf("%d\n",n);
	}
	
	return 0;
}

\(100\) 分部分

思路

考时就想到了,由于算错时间复杂度,觉得肯定会炸,于是打了 \(70\) 分跑路。

考后发现了自己的 zz 错误。

讲一下做法:

先预处理出 \(1\sim 10^7+5\) 内所有不满足条件的数。(注意这里的边界)

如果经过判断一个数 \(x\) 满足 \(f(x)=1\),那么它的所有倍数都一定满足 \(f(xk)=1\)。如果 \(x\) 满足 \(f(x)=0\),那么把它加入 \(num\) 数组中。

然后询问的时候:二分查找 \(num\) 数组中有没有这个数(可以用 binary_searchlower_bound,如果用 lower_bound,可以判断结果是否等于 \(n\),如果不等于,那么输出 \(-1\))。

随后二分查找在 \(num\) 数组中第一个大于等于 \(n+1\) 的数,输出这个数即可。

代码

const int ma=1e7+5;

int num[ma];

bool mark[ma]; 

int T,n;

int idx;

inline bool chk(int x)
{
	while(x!=0)
	{
		if(x%10==7)
		{
			return true;
		}
		
		x/=10;
	}
	
	return false;
} 

inline void init(int ri)
{
	for(register int i=1;i<=ri;i++)
	{
		if(chk(i)==true)
		{
			mark[i]=true;
		}
		
		if(mark[i]==false)
		{
			num[++idx]=i;
		}
		
		else
		{
			for(register int j=i*2;j<=ri;j+=i)
			{
				mark[j]=true;
			}
		}
	} 
}

int main(void)
{
	init(ma);
	
	T=read();
	
	while(T--)
	{
		n=read();
		
		if((*lower_bound(num+1,num+idx+1,n))!=n)
		{
			puts("-1");
		}
		
		else
		{
			int p=*lower_bound(num+1,num+idx+1,n+1);
			
			printf("%d\n",p);
		}
	}
	
	return 0;
}

\(\rm BB~In~Last\)

这次 NOIP 直接挂完了,感觉自己学一年的 \(\verb!OI!\) 简直是个笑话。

人们总是说,时间是世界上最公平的,时间也是世界上最不公平的。我记住了,但没有真正理解,现在,我想我理解了。世界上没有真正的感同身受,即使把这条道理抄成千上万遍,也没有亲身经历过一次来的实在。

对于我这种一年时间几乎 \(\dfrac{3.7}{12}\) 的时间都在颓废的人,时间总是悄悄的从我的手中、键盘上溜走,等我缓过神来,往往已经是深夜了。

更让我感到绝望的是:有天赋的人往往比普通人更为勤奋。

可笑的是,这一年内,我就这样木然地看着旁人和自己的差距越拉越大,兴致来了,感叹几句,然后继续颓废。

已经初二了,我还有多少时间啊......

\(\texttt{\color{blue}即使没有舞台,你也要做你人生的主角。}\)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM