【TJOI2013】数字根

来源:互联网 发布:java软件编程培训中心 编辑:程序博客网 时间:2024/06/10 17:14

【TJOI2013】数字根

【题目描述】

一个数字的数字根定义为:这个数字每一位的数字加起来求和,反复这个过程直到和小于10。例如,64357的数字根为7,因为6+4+3+5+7=25,2+5=7.一个区间的数字根定义为这个区间所有数字和的数字根。
给定一个序列A1,A2,A3,…,An,你需要回答一些询问。每一个询问给定一个区间[L,R],求出这个区间所有连续子区间里最大的前5个不同的数字根。不够5个的用-1补全。

【输入】

第一行一个整数N,表示序列的长度。第二行是N个整数Ai(0≤Ai≤10^9)。第三哪行是一个整数Q,表示询问次数。接下来Q行,每一行两个正整数l,r,表示询问区间。(1≤l≤r≤N)

【输出】

Q行,表示每一个查询区间所有连续子区间里最大的前5个不同的数字根,按降序输出,输出用空格隔开。

【输入样例】

5
101 240 331 4 52
3
1 3
4 5
1 5

【输出样例】

8 7 6 4 2
7 4 2 -1 -1
9 8 7 6 4

【数据范围】

30%的数据,N≤1000,Q≤1000
100%的数据,N≤100000,Q≤100000

【题解】

一个数的数字根等于这个数除以9的余数(若为余数为0则数字根为9),这是以前玩一个游戏时学到的= =

数字的和/差的数字根等于数字的数字根的和/差的数字根,有些拗口,总之读入数据时直接处理为数字根,这个做法不会影响后面的计算。

为了方便找出区间数字根,把原数列处理为前缀和,算前缀和的过程中也把前缀和处理为数字根。

接下来就可以开始枚举了,是的,双重嵌套暴力枚举。为什么可以这样?因为连续一大段区间的子区间数字根小于5是小概率事件,因为数字根之间加减满足原数加减的性质。一但发现5~9的数字根都出现了,直接停止枚举就好,答案就是9 8 7 6 5。

对了,原题有一句提示“输入较大,C++建议使用scanf()进行输入”,cin已经无法直视了=_=

【代码】

枚举,速度还不错。

【TJOI2013】数字根#代码
0 0