jzoj. 1302. DigitalCounter
来源:互联网 发布:黄磊人设崩塌 知乎 编辑:程序博客网 时间:2024/05/21 19:23
我们有一个N位数字的电子表,当时间到达10^N-1时,下一秒就归0。下面我们给出数字0 到 9的模拟图。
对于每个数字,相邻两个+之间会有一根电子管,当显示该数字时,这些电子管就会发亮。如上图所示:数字0到9,它们的电子管数量分别是:6、2、 5、 5、 4、 5、 6、 3、 7、 5。
设现在的时刻是X, 那么可以算出该时有多少根电子管是亮的。比如:现在时刻是:99,那么共有5 + 5= 10根电子管是亮的。假如从现在时刻开始,再过Y秒后,时刻显示为Z, 我们的问题是:求最小的Y,使得时刻Z发亮的电子管数量与时刻X发亮的电子管数量相等。如:现在X = 99 ,那么再过Y = 5 秒后, 时刻变成了Z = 04, 而时刻Z发亮的电子管数量 = 6 + 4 = 10。于是Y = 5就是你要求的数。
Input
第一行:一个整数N,表示电子表是10^N进制的。1 <= N <= 15。
第二行:一个整数X, 表示现在的时刻,可能有前导0。X有N位数字。
Output
一行:最小的整数Y, 表示从现在X时刻开始,再过Y秒,得到的时刻Z发亮的电子管数量与时刻X发亮的电子管数量相等。
Sample Input
3
007
Sample Output
11
Data Constraint
Hint
【样例说明】
因为数字007有6+6+3 =15根电子管发亮,所以过11秒后,电子表显示数字018时,才能满足发亮的电子管数量相等。018时刻发亮的电子管数量 = 6 + 2 + 7 = 15
【数据说明】
对于30%数据,N < 7.
分析:想让数变大,而又发光的电子管数不变。对于改变第i位,则i+1~n位可以选1~9任何数,电子管数的范围为(n-i) * 2~(n-i) * 7;全是1或者全是8。那为什么中间的数都能组成呢??
假设后面3位都可以选1–9,如果后面全为2,则集合为
{2,2,2} sum=6
{2,2,3} sum=7
……
{2,2,7} sum=11
然后就是
{2,3,7} sum=12
{2,4,7} sum=13
……
然后再变第一位,显然,我们每次都可以在某位加1,因为{2–7个电子管都有对应的数字,这里所对应的数字可能有多个}
总之,这个范围内的所有的数都可以得到。
我们先求第一位到第i位使用了多少个电子管,也就是前缀和。我们从后面枚举一位,因为越在后面,改变后的变化值越小。我们把第i位的x变为x+1~9中的某个数j时,判断
(n-i) * 2<=sum[i-1]+a[j]<=(n-i) * 7 {a[j]表示显示是j要用多少个电子管}
就可以求出要在哪一位开始改变。
(1)我们设要变得位为p,那么对于后面的i-p位中的第l位,都是0–9中的某个数,当我们选了一个数为k时,这时我们要判断:
(n-l) * 2<=changesum[l-1]+a[k]<=(n-l) * 7
这里的changesum指的是,改变后到这一位用的电子管数,可以用一个变量g来统计。
(2)如果p=0,说明往大改无法找到一个合法的数,我们从0开始找,也就是归0。再按上述方法判断。
若第一个合法数为y,原数为x,第一种答案就是y-x,第二种答案就是max-x+y{max=10^n}
代码:
const a:array [0..9] of longint=(6,2,5,5,4,5,6,3,7,5);var n,i,t,j:longint; sum:array [0..20] of longint; x,y,pow,p,e,g:int64; s:string;procedure find;begin for i:=n-1 downto 1 do begin t:=ord(s[i])-48; for j:=t+1 to 9 do if (sum[i-1]+a[j]+(n-i)*7>=sum[n]) and (sum[i-1]+a[j]+(n-i)*2<=sum[n]) then begin p:=i; e:=j; exit; end; end;end;begin readln(n); readln(s); pow:=1; for i:=1 to n do begin t:=ord(s[i])-48; sum[i]:=sum[i-1]+a[t]; x:=x*10+t; pow:=pow*10; end; for i:=t+1 to 9 do if a[i]=a[t] then begin writeln(i-t); exit; end; find;if p<>0 then begin g:=sum[i-1]+a[e]; s[p]:=chr(e+48); for i:=p+1 to n do for j:=0 to 9 do begin if (g+a[j]+(n-i)*7>=sum[n]) and (g+a[j]+(n-i)*2<=sum[n]) then begin s[i]:=chr(j+48); g:=g+a[j]; break; end; end; val(s,y); writeln(y-x); endelse begin for i:=1 to n do for j:=0 to 9 do begin if (g+a[j]+(n-i)*7>=sum[n]) and (g+a[j]+(n-i)*2<=sum[n]) then begin s[i]:=chr(j+48); g:=g+a[j]; break; end; end; val(s,y); writeln(pow-x+y); end;end.
- jzoj. 1302. DigitalCounter
- 高中OJ1302. DigitalCounter
- [JZOJ 3424] 粉刷匠 && [JZOJ 4254] 集体照
- [JZOJ 1280]最大匹配
- [JZOJ 1281]旅行
- [1282 JZOJ]资源勘探
- [JZOJ 1283]排序统计
- JZOJ NOIP2014模拟 8.12
- JZOJ NOIP2014模拟 8.13
- [JZOJ 1598]文件修复
- 【JZOJ 3111】单词查找
- 【JZOJ 3112】开会
- JZOJ 3463 军训
- 【JZOJ】3169 生产汽车
- 【JZOJ】3187 的士
- 【JZOJ】3188 找数
- 【JZOJ】3196 物理
- 【JZOJ 4353】distance
- 2017各大知名互联网公司Android面试题
- Java并发编程--CAS(Compare And Swap)无锁算法
- 2017.7.15 学习HDFS提供的JAVA API
- C++中面向对象的相关内容
- python核心高级学习总结1---------*args和**kwargs
- jzoj. 1302. DigitalCounter
- SQLite+Qt 图书管理系统设计(具体实现)
- [OSX]为终端(Terminal)添加色彩
- 超级台阶
- llvm IR 语法小例子
- Play framework路由(Http route)
- SQL drop和truncate与drop的区别
- React Native自定义控件【底部抽屉菜单】
- 亚马逊云上搭建VPN服务器