首页 > 代码库 > 【bzoj入门】3189 猜数字(数学,搜索)
【bzoj入门】3189 猜数字(数学,搜索)
Description
味味最近在玩猜数字的游戏,现在她也希望你来玩一下这个游戏。猜数字游戏的规则是这样的,告诉你一个正整数 n
(2<=n<=11),然后味味心中会想一个 n 个数字组成的数字串 (数字串最前面若干位可能是 0)。味味会随意排列 n
位数上的数字,这样可能产生 n!个 n 位数。(n!=1×2×3×4×5×......×n,n!念作“n 阶乘”).比如味味想了一
个三位数 abc,那么一共会产生六个三位数,分别为 abc,acb,bac,bca,cab,cba然后味味会把这 n!个 n 位数求和得
到 S(若某数第一位开始有若干个 0,则求和时这些 0 舍去。如有数“0123”,则求和时加到 s 中的值是 123),她
会告诉你总和 S 减去她心中想的那个数的值,请你猜出味味心中想的那个数。
(2<=n<=11),然后味味心中会想一个 n 个数字组成的数字串 (数字串最前面若干位可能是 0)。味味会随意排列 n
位数上的数字,这样可能产生 n!个 n 位数。(n!=1×2×3×4×5×......×n,n!念作“n 阶乘”).比如味味想了一
个三位数 abc,那么一共会产生六个三位数,分别为 abc,acb,bac,bca,cab,cba然后味味会把这 n!个 n 位数求和得
到 S(若某数第一位开始有若干个 0,则求和时这些 0 舍去。如有数“0123”,则求和时加到 s 中的值是 123),她
会告诉你总和 S 减去她心中想的那个数的值,请你猜出味味心中想的那个数。
输入共包含两行。第一行一个整数 n(含义如前面所述),第二行一个正整数S,表示 n!个数的总和减去味味心中那个数的值。
2≤n≤11 ,0≤S≤10^18。如果该数第一位开始有若干个 0,则输出时这些 0 也必须输出(详见样例 3)。
2≤n≤11 ,0≤S≤10^18。如果该数第一位开始有若干个 0,则输出时这些 0 也必须输出(详见样例 3)。
思路:设已经知道答案每个位置上的数,推导公式可发现S只与数位之和与原数有关
直接搜索原数会超时,所以枚举0-9各自出现了几次,利用S与数位之和反推出原数,验证0-9出现的次数是否符合
1 var a,b:array[0..9]of longint; 2 pt,i,n:longint; 3 s,q,ans,m,max:int64; 4 p:boolean; 5 6 procedure dfs(k,g,t:longint); //g shengyugeshu t shuweihe 7 var i,tt:longint; 8 flag:boolean; 9 q:int64; 10 11 begin 12 if p then exit; 13 14 if k=10 then 15 begin 16 if g>0 then exit; 17 q:=t*m-s; ans:=q; 18 if q>max then exit; 19 if q<0 then exit; 20 fillchar(b,sizeof(b),0); tt:=n; 21 while q>0 do 22 begin 23 inc(b[q mod 10]); 24 q:=q div 10; dec(tt); 25 end; 26 b[0]:=b[0]+tt; 27 flag:=true; 28 for i:=0 to 9 do 29 if a[i]<>b[i] then begin flag:=false; break; end; 30 if flag then begin pt:=tt; p:=true; end; 31 exit; 32 end; 33 34 if g=0 then 35 begin 36 dfs(10,0,t); 37 exit; 38 end; 39 40 {if k=9 then 41 begin 42 a[9]:=g; 43 dfs(10,0,t+g*9); 44 a[9]:=0; 45 exit; 46 end; } 47 48 for i:=0 to g do 49 begin 50 a[k]:=i; 51 dfs(k+1,g-i,t+k*i); 52 a[k]:=0; 53 if p then exit; 54 end; 55 end; 56 57 begin 58 59 readln(n); 60 for i:=1 to n do m:=m*10+1; 61 for i:=1 to n-1 do m:=m*i; 62 readln(s); 63 for i:=1 to n do max:=max*10+9; 64 p:=false; 65 dfs(0,n,0); 66 for i:=1 to pt do write(0); 67 write(ans); 68 69 end.
【bzoj入门】3189 猜数字(数学,搜索)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。