1. 题目
循环数
Description
Leve同学又来出水题了。。。。。。。。。。。
循环数是那些不包括0且没有重复数字的整数(比如81362)并且还应同时具有一个有趣的性质, 就像这个例子:
如果你从最左边的数字开始(在这个例子中是8)向右数最左边这个数(如果数到了最右边就回到最左边),你会停止在另一个新的数字(如果停在一个相同的数字上,这个数就不是循环数).就像: 8 1 3 6 2 从最左边接下去数8个数字: 1 3 6 2 8 1 3 6 所以下一个数字是6
重复这样做 (这次从“6”开始数6个数字) 并且你会停止在一个新的数字上: 2 8 1 3 6 2, 也就是2
再这样做 (这次数两个): 8 1
再一次 (这次一个): 3
又一次: 6 2 8 这时你回到了起点,在经过每个数字一次后回到起点的就是循环数。如果你经过每一个数字一次以后没有回到起点, 你的数字不是一个循环数。
给你一个数字 M (在1到9位之间), 找出第一个比 M大的循环数, 输出数据保证结果能用一个无符号长整型数装下。
Input
仅仅一行, 包括M
Output
仅仅一行,输出第一个比M大的循环数。
Sample Input
81361
Sample Output
81362
2. 题目实质
模拟,求一个符合条件的数。
3. 算法
模拟,但有许多小技巧。
首先,用字符串读入那个数,然后用 str , val 给他进行加一减一的操作。(当然,如果诸位仁兄想直接用高精加来加一减一也没问题……)然后将这个数依次加一,再判断新出现的数有没有重复的数字(至于 0 啊, length(s)啊,是不用特判的,一遍模拟就全出来了),然后就开始对这个数进行模拟。
模拟很简单,就照它说的按一定的规律往后数数字就可以了,注意 mod 完了之后一个数的范围。
然后就是答案了。
4. 注意事项
这个题跟那道计算日期一样,不用想什么优化(因为优化的结果往往是 WA ),就直接找他说的一个一个加就行了,反正是第一题, NOIP 也不会那么狠,估计时间复杂度的话,一定要靠谱一点。
5. 时空复杂度
不详,由到那个数停止决定。
6. 程序代码
Leve (Pascal)
const
maxn=10;
type
strr=string[maxn];
var
s:strr;
code:longint;
a:array[1..maxn]of boolean;
b:array['0'..'9']of boolean;
function judge(ts:strr):boolean;
var
i:integer;
begin
fillchar(b,sizeof(b),0);
judge:=true;
for i:=1 to length(ts) do
if not b[ts[i]] then b[ts[i]]:=true else exit(false);
end;
function check(ts:strr):boolean;
var
need,p,le:integer;
begin
fillchar(a,sizeof(a),0);
check:=false;
le:=length(ts);
need:=le;
p:=1;
repeat
p:=(p+ord(s[p])-ord('0'))mod le;
if p=0 then p:=le;
if a[p] then exit(false) else begin a[p]:=true; dec(need); end;
until need=0;
if p=1 then exit(true) else exit(false);
end;
begin
assign(input,'number.in'); reset(input);
assign(output,'number.out'); rewrite(output);
readln(s);
repeat
val(s,code);
str(code+1,s);
until judge(s) and check(s);
writeln(s);
close(input); close(output);
end.