'''
标题:三体攻击
【题目描述】
三体人将对地球发起攻击。为了抵御攻击,地球人派出了 A × B × C 艘战舰,在太空中排成一个 A 层 B 行 C 列的立方体。其中,第 i 层第 j 行第 k 列的战舰(记为战舰 (i, j, k))的生命值为 d(i, j, k)。
三体人将会对地球发起 m 轮“立方体攻击”,每次攻击会对一个小立方体中的所有战舰都造成相同的伤害。具体地,第 t 轮攻击用 7 个参数 lat, rat, lbt, rbt, lct, rct, ht 描述;
所有满足 i ∈ [lat, rat],j ∈ [lbt, rbt],k ∈ [lct, rct] 的战舰 (i, j, k) 会受到 ht 的伤害。如果一个战舰累计受到的总伤害超过其防御力,那么这个战舰会爆炸。
地球指挥官希望你能告诉他,第一艘爆炸的战舰是在哪一轮攻击后爆炸的。
【输入格式】
从标准输入读入数据。
第一行包括 4 个正整数 A, B, C, m;
第二行包含 A × B × C 个整数,其中第 ((i − 1)×B + (j − 1)) × C + (k − 1)+1 个数为 d(i, j, k);
第 3 到第 m + 2 行中,第 (t − 2) 行包含 7 个正整数 lat, rat, lbt, rbt, lct, rct, ht。
【输出格式】
输出到标准输出。
输出第一个爆炸的战舰是在哪一轮攻击后爆炸的。保证一定存在这样的战舰。
【样例输入】
2 2 2 3
1 1 1 1 1 1 1 1
1 2 1 2 1 1 1
1 1 1 2 1 2 1
1 1 1 1 1 1 2
【样例输出】
2
【样例解释】
在第 2 轮攻击后,战舰 (1,1,1) 总共受到了 2 点伤害,超出其防御力导致爆炸。
【数据约定】
对于 10% 的数据,B = C = 1;
对于 20% 的数据,C = 1;
对于 40% 的数据,A × B × C, m ≤ 10, 000;
对于 70% 的数据,A, B, C ≤ 200;
对于所有数据,A × B × C ≤ 10^6, m ≤ 10^6, 0 ≤ d(i, j, k), ht ≤ 10^9。
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
'''# 思路:# 1)范围攻击用差分记录,这样每次攻击只需花O(1)的时间来记录# 2)二分攻击次数,攻破了,就在下半区二分回复血量,没攻破就在上半区再二分继续攻击 O(logm)# 3)每次检查是否攻破,求差分前缀和求最终血量,再遍历ABC个格子,看是否有血量小于0来判断 O(ABC)from copy import copy
a, b, c =0,0,0defgetX(i, j, k):'''
:param i:
:param j:
:param k:
:return: 转为1维索引
'''return((i -1)* b + j -1)* c + k
defadd(cc, i, j, k, h):'''
修改ijk坐标的差分数组的值
:param cc:
:param i:
:param j:
:param k:
:param h:
:return:
'''if i < a and j < b and k < c:
cc[getX(i, j, k)]+= h
defop(cc, atk, f):'''
:param cc: 差分数组
:param atk: 元组,数据是一次攻击的相关参数
:param f: 1或者-1,代表攻击还是回复血量
:return: void
'''
la, ra, lb, rb, lc, rc, h = atk
h = h * f
add(cc, la, lb, lc, h)
add(cc, la, rb +1, lc,-h)
add(cc, la, lb, rc +1,-h)
add(cc, la, rb +1, rc +1, h)
add(cc, ra +1, lb, lc,-h)
add(cc, ra +1, rb +1, lc, h)
add(cc, ra +1, lb, rc +1, h)
add(cc, ra +1, rb +1, rc +1,-h)defcheck(cc, d):'''
三个维度累加,得差分数组的前缀和,就能得到每个点上的当前血量的变化量
:param cc:
:param d:
:return:
'''# 差分数组的前缀和,来自差分数组的复制
_sum = copy(cc)for i inrange(2, a):for j inrange(1, b):for k inrange(1, c):
_sum[getX(i, j, k)]+= _sum[getX(i -1, j, k)]for i inrange(1, a):for j inrange(2, b):for k inrange(1, c):
_sum[getX(i, j, k)]+= _sum[getX(i, j -1, k)]for i inrange(1, a):for j inrange(1, b):for k inrange(2, c):
_sum[getX(i, j, k)]+= _sum[getX(i, j, k -1)]# 遍历每个点,检查变化量是否大于原始血量for i inrange(1, a):for j inrange(1, b):for k inrange(1, c):
index = getX(i, j, k)if _sum[index]> d[index]:returnTruereturnFalseif __name__ =='__main__':# import sys## sys.stdin = open('/Users/zhengwei/data/in6.txt')
A, B, C, m =(int(x)for x ininput().strip().split(' '))
a, b, c = A +1, B +1, C +1
_d =[int(x)for x ininput().strip().split(' ')]# 原始血量数据# 统一为三维情况
d =[0for _ inrange(a * b * c)]# 原始血量(为了便于从1开始,增加长宽高,可用ijk定位)
index =0for i inrange(1, a):for j inrange(1, b):for k inrange(1, c):
d[getX(i, j, k)]= _d[index]
index +=1
cc =[0for _ inrange(a * b * c)]# 差分数组# 攻击数据
atk =[tuple()]# 注意,下标从1开始,所以要占位一个空的元组作为0号元素for i inrange(m):
atk.append(tuple(int(x)for x ininput().strip().split(' ')))# print(atk[i])# 二分攻击次数
l, r, lastMid =1, m,0while l < r:
mid =(l + r)>>1if lastMid < mid:# 上一次攻击没有攻破,继续攻击for i inrange(lastMid +1, mid +1):
op(cc, atk[i],1)# 修改差分数组elif lastMid > mid:# 上一次攻破了,恢复血量for i inrange(mid +1, lastMid +1):
op(cc, atk[i],-1)# 如果爆了,调整边界if check(cc, d):
r = mid
else:
l = mid +1
lastMid = mid
print(r)
17 螺旋折线
提示:以右下角对角线上的点为参照点(等差数列),测算给定的点到参照点要走的距离
'''
标题:螺旋折线
如图p1.png所示的螺旋折线经过平面上所有整点恰好一次。
对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。
例如dis(0, 1)=3, dis(-2, -1)=9
给出整点坐标(X, Y),你能计算出dis(X, Y)吗?
【输入格式】
X和Y
对于40%的数据,-1000 <= X, Y <= 1000
对于70%的数据,-100000 <= X, Y <= 100000
对于100%的数据, -1000000000 <= X, Y <= 1000000000
【输出格式】
输出dis(X, Y)
【样例输入】
0 1
【样例输出】
3
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
'''def_sum(a0, n, d):return(2* a0 +(n -1)* d)* n //2if __name__ =='__main__':# 以右下角对角线上的点为参照点,测算给定的点到参照点要走的距离
X, Y =(int(i)for i ininput().strip().split(' '))
d, n =0,0# 距离和第几圈if Y >0andabs(X)<= Y:
n = Y
d = Y - X +2* Y
elif X >0andabs(Y)<= X:
n = X
d = Y + X
elif Y <=0and Y -1<= X <=-Y:
n =-Y
d =-(-Y - X)elif X <0and X +1<= Y <=-X:
n =-X -1
d =-(Y - X -1-2* X -1)print(_sum(1,2* n,1)*2- d)