其实这道题目不难,主要要求我们有一个清晰地思路
首先可以按位数讨论,这里我把1~9单独讨论了
因为除了1位数,每个位数开头的数的开头数字1前面都是-号
然后考虑位数的奇偶性
当位数为奇数的时候比较简单
举个例子
-1+0-0
+1-0+1
-1+0-2
+1-0+3
不难发现,奇位数从开头的数开始,相邻两个数数字和都是1,这就非常好统计了
如果位数为偶数,则这位数的一个数排完之后,下一个数的开头符号还是上一个数的开头符号
就是-1+0 -1+1 -1+2……这个意思
于是我们就要数位dp来处理
1 var f:array[0..20,0..10] of int64; 2 d,c:array[0..20] of int64; 3 ans,x,n:int64; 4 s,i,m,j,k,t:longint; 5 6 begin 7 readln(n); 8 if n<=9 then 9 begin 10 for i:=1 to n do 11 if i mod 2=1 then ans:=ans+i else ans:=ans-i; 12 writeln(ans); 13 halt; 14 end; 15 ans:=5; 16 m:=0; 17 x:=n; 18 while x<>0 do 19 begin 20 inc(m); 21 d[m]:=x mod 10; 22 x:=x div 10; 23 end; 24 c[1]:=1; 25 for i:=2 to m do 26 c[i]:=c[i-1]*10; 27 for i:=0 to 9 do 28 f[1,i]:=i; 29 for i:=2 to m do //开头为j,是i位数的每个数的数字和(注意这里默认每个数的开头都是+) 30 for j:=0 to 9 do 31 begin 32 f[i,j]:=c[i]*j; 33 for k:=0 to 9 do 34 f[i,j]:=f[i,j]-f[i-1,k]; 35 end; 36 for i:=2 to m-1 do //位数小于n的数字和 37 begin 38 if i mod 2=0 then 39 begin 40 for j:=1 to 9 do 41 ans:=ans-f[i,j]; 42 end 43 else ans:=ans+9*c[i] div 2; 44 end; 45 if m mod 2=1 then //n位数为奇数可以直接计算 46 begin 47 ans:=ans+(n-c[m]+1) div 2; 48 if n mod 2=0 then 49 begin 50 for i:=m downto 1 do 51 if i mod 2=0 then ans:=ans+d[i] 52 else ans:=ans-d[i]; 53 end; 54 end 55 else begin 56 k:=-1; 57 for i:=m downto 1 do //n位数为偶数逐位统计 58 begin 59 if i=m then s:=1 else s:=0; 60 for j:=s to d[i]-1 do 61 ans:=ans+k*f[i,j]; 62 ans:=ans+k*(n-d[i]*c[i]+1)*d[i]; //这里要好好琢磨 63 n:=n-d[i]*c[i]; 64 k:=k*(-1); 65 end; 66 end; 67 writeln(ans); 68 end.