51Nod 1087 1 10 100 1000 思维题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jsszwc/article/details/86934277

题目:

https://www.51nod.com/Challenge/Problem.html#!#problemId=1087

题意:

1,10,100,1000…组成序列1101001000…,求这个序列的第N位是0还是1。

思路:

把每一个组成序列的数字 1 0 x 10^x 看成一项,用二分法寻找到第 m m 项:第 1 1 项到第 m m 项拼接起来的长度小于等于 n n 。求出第 1 1 项到第 m m 项拼成的长度,用 n n 减去这个长度,如果减的结果为 1 1 或者 n n 本身为 1 1 ,那么答案就是 1 1 ,否则为 0 0 。二分的上限是 1 0 5 10^5 ,因为第 1 0 5 10^5 项拼成的长度肯定大于题目限定的数据范围,故复杂度 O ( l o g 2 1 0 5 ) O(log_2^{10^5})

更直接更暴力的方法是找规律,看讨论区才知道的:
从第 1 1 项拼到第 m m 项得出的长度分别是: m ( m + 1 ) 2 = 1 , 3 , 6 , 10 , . . . \frac{m(m+1)}{2} = 1,3,6,10,...
输出 1 1 n n 分别是 1 , 2 , 4 , 7 , 11 , . . . 1,2,4,7,11,... ,全部减去 1 1 0 , 1 , 3 , 6 , 10 , . . . 0,1,3,6,10,...
也就是
n 1 = m ( m + 1 ) 2 n-1=\frac{m(m+1)}{2}
判断 n n 是否满足这个一元二次方程就可以了

代码:

Python

def main():
    t = int(input())
    for i in range(t):
        n = int(input())

        ans = -1
        l, r = 0, 100000
        while l <= r:
            mid = (l + r) // 2
            if mid*(mid+1)//2 <= n:
                l = mid + 1
                ans = mid
            else:
                r = mid - 1

        if n == 1 or n - ans*(ans+1)//2 == 1:
            print(1)
        else:
            print(0)


main()

#找规律解法
# import math
# 
# def main():
#     t = int(input())
#     for i in range(t):
#         n = int(input())
#         n = 2 * (n - 1)
#         t = int(math.sqrt(n))
#         if t * (t+1) == n:
#             print(1)
#         else:
#             print(0)
# 
# 
# main()

猜你喜欢

转载自blog.csdn.net/jsszwc/article/details/86934277