1026: [SCOI2009]windy数
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 274 Solved: 130
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
1 10 25 50
Sample Output
【输出样例一】 【输出样例二】
9 20
【数据规模和约定】
20%的数据,满足 1 <= A <= B <= 1000000 。
100%的数据,满足 1 <= A <= B <= 2000000000 。
=====================================================================================================
如果我当年考SCTSC的话,我看到题肯定马上叫监考,问他限制代码规模多少k……
不会显然可以打表,限制代码长度的话可以小于10000000的暴力,大于10000000的打表……其实,Cena的代码大小限制根本就是摆设,用Ubuntu的话另当别论了……
咳咳……说正经的……
这个题我觉得是SCTSC Day1里面比较水的题……但是不怎么容易得分,毕竟数字统计这类的题细节是需要多加注意的。
显然1..100000(好多0) 的可以按位预处理递推得到。
f[i,j]表示位数为i,最高位为j范围内Windy数的个数。
初始状态:f[1,i]=0 , i∈[0,9]
f[i,j]=∑(f[i-1,k]) , |j-k|≥2
然后……一位一位地找就行了……
但是要注意,一个数的个位数处理与其他位置的数处理有所不同……
/**************************************************************
Problem: 1026
User: Delostik
Language: Pascal
Result: Accepted
Time:0 ms
Memory:248 kb
****************************************************************/
program SCOI_2009_WindyNumber;
var BASE:Array[1..10]of longint;
f:array[1..10,0..9]of longint;
a,b:longint;
procedure init;
var i,j,k:longint;
begin
BASE[1]:=1;
for i:=2 to 10 do BASE[i]:=BASE[i-1]*10;
readln(a,b);
for i:=0 to 9 do f[1,i]:=1;
for i:=2 to 10 do
for j:=0 to 9 do
for k:=0 to 9 do
if abs(j-k)>=2 then inc(f[i,j],f[i-1,k]);
end;
function count(n:longint):longint;
var w,i,j,cur,pre,last:longint;
begin
if n=0 then exit(0);
count:=0;
w:=10;
while BASE[w]>n do dec(w);
for i:=1 to w-1 do
for j:=1 to 9 do
inc(count,f[i,j]);
cur:=n div BASE[w];
for i:=1 to cur-1 do inc(count,f[w,i]);
n:=n mod BASE[w];
pre:=cur;
for i:=w-1 downto 1 do
begin
cur:=n div BASE[i];
if i<>1 then
begin
for j:=0 to cur-1 do
if abs(pre-j)>=2 then inc(count,f[i,j]);
end
else
for j:=0 to cur do
if abs(pre-j)>=2 then inc(count,f[i,j]);
if abs(cur-pre)<2 then exit;
pre:=cur;
n:=n mod BASE[i];
end;
end;
procedure solve;
begin
writeln(count(b)-count(a-1));
end;
begin
init;
solve;
end.