Educational_Round#76_(Div2)

Round#599(div2)

概要

A,B,C是水题,很快就a掉了,D题当时没有想出来,还看错了题目。
补题的时候用了python写abc,发现python真的好方便啊,牛逼
看了官方的题解和别人的代码,觉得别人真的猛啊,自己思维题还是不够猛。

D. Yet Another Monster Killing Problem

题意
给n个怪物的能力值,要按顺序击杀他们。
有m个勇士,每个勇士有能力值和耐力值两种属性
每天只能派一个勇士去杀怪,如果勇士的能力值大于等于怪物的能力值就可以击杀,击杀怪物掉一点耐力值,耐力值为0就要出来
问最小需要几天能杀完怪物,勇士可以随便用,如果不能完成输出-1
题解:
在这里插入图片描述
用一个 b s t bst bst数组, b s t [ i ] bst[i] bst[i]表示勇士耐力值大于等于i的最大能力值,如果已经击杀 c n t cnt cnt只怪物,如果 a c n t + 1 > b s t i a_{cnt+1} > bst_i acnt+1>bsti,那么结果就是 − 1 -1 1,不然就一直保持 m a x c n t < i ≤ c n t + x a i ≤ b s t x max_{cnt<i\leq cnt+x}a_i\leq bst_x maxcnt<icnt+xaibstx

这部分代码没有见过,太猛了!

for(int i = n - 1; i >= 0; --i)
			bst[i] = max(bst[i], bst[i + 1]);	
#include <bits/stdc++.h>

using namespace std;

const int N = int(2e5) + 99;

int t;
int n;
int a[N];
int m;
int p[N], s[N];
int bst[N];

int main() {	
	scanf("%d", &t);
	for(int tc = 0; tc < t; ++tc){
		scanf("%d", &n);
		for(int i = 0; i <= n; ++i) bst[i] = 0;
		for(int i = 0; i < n; ++i)
			scanf("%d", a + i);
		scanf("%d", &m);
		for(int i = 0; i < m; ++i){
			scanf("%d %d", p + i, s + i);
			bst[s[i]] = max(bst[s[i]], p[i]);
		}
		for(int i = n - 1; i >= 0; --i)
			bst[i] = max(bst[i], bst[i + 1]);	
		

		int pos = 0;
		int res = 0;
		bool ok = true;
		while(pos < n){
			++res;
			int npos = pos;
			int mx = 0;
			while(true){
				mx = max(mx, a[npos]);
				if(mx > bst[npos - pos + 1]) break;
				++npos;
			}
	
			if(pos == npos){
				ok = false;
				break;
			}
			pos = npos;
		}

		if(!ok) res = -1;
		printf("%d\n", res);
	}

	return 0;
}           

A. Two Rival Students

题意
有[1,n]个学生,执行k次操作,每次操作能把相邻的两个学生交换位置,给两个学生的初始位置,求最远的距离( ∣ a − b ∣ |a-b| ab)

思路
m i n ( n − 1 , ∣ a − b ∣ + k ) min(n-1,|a-b|+k) min(n1,ab+k)就完事了

for _ in range(int(input())):
    n,k,a,b = map(int,input().split())
    print(min(n-1,abs(a-b)+k))

B. Magic Stick

题意
有一根棍子,初始长度n,每次有两种操作
①n = n - 1
②n = 1.5n (if n % 2 == 0)
给初始长度和目标长度,输出YES和NO

思路
分情况就完事了

for _ in range(int(input())):
    a,b = map(int,input().split())
    if (a == 1 and b > 1) or (a > 1 and a < 4 and b > 3):
        print("NO")
    else:
        print("YES")

C. Dominated Subarray

题意
给一个数组,求最小子串的长度,子串中某个元素至少出现两次
思路:
p r e [ i ] pre[i] pre[i] 存数字 i i i上一次出现的位置,不停取最小即可

for _ in range(int(input())):
    n = int(input())
    L = input().split()
    P = {}
    ans = 1e18
    for i in range(len(L)):
        if(L[i] in P.keys()):
            ans = min(ans,i - P[L[i]] + 1)
        P[L[i]] = i
    print(-1 if ans == 1e18 else ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值