[USACO2.2]循环数 Runaround Numbers

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/84861791

链接

洛谷
USACO


大意

定义一种数,满足以下要求

  1. 没有0
  2. 没有重复出现的数字
  3. 每次往后跳第一个数字个数字(若超过则按环处理),能重新跳回第一个数字,且不死循环

举个栗子:
81362 往后跳8次,跳到6,往后跳6次,跳到2,往后跳2次跳到1,往后跳1次跳到3,往后跳3次,跳到8。

n n 之后的第一个循环数
n < 2 31 n< 2^{31}


思路

暴力模拟


代码

/*
ID:hzbismy1
LANG:C++
TASK:runround
*/
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;int n,len,i,x,a[21];
inline char Getchar()
{
    static char buf[100000],*p1=buf+100000,*pend=buf+100000;
    if(p1==pend)
	{
        p1=buf; pend=buf+fread(buf,1,100000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline int read()
{
	char c;int d=1,f=0;
	while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void write(register long long x)
{
	if(x<0)write(45),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
	return;
}
inline bool xh(register int x)
{
	len=0;
	while(x){a[++len]=x%10;x/=10;}
	reverse(a+1,a+1+len);
	bool vis[31]={1};
	int k=1;
	for(register int i=1;i<=len;i++)
	{
		if(vis[a[k]]) return false;//出现过
		vis[a[k]]=true;//标记
		k=(k+a[k]-1)%len+1;//往后跳
	}
	return k==1;
}
signed main()
{
	file(runround);
	n=read();
	for(i=n+1;!xh(i);i++);
	write(i);putchar(10);
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/84861791
今日推荐