【模拟】签订协议(nowcoder 217601)

该博客探讨了一种协议书传递的问题,其中目标是使所有数都能匹配,并确定最少需要传递多少圈。通过排序和比较数值初始位置,可以确定是否需要额外传圈。博主提供了解题思路和代码实现,主要涉及算法和数据结构的知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

签订协议

nowcoder 217601

题目大意

给出n个数,现在有一个协议书,让你从1传到n,然后传回1,继续传下去
对于第i个数,如果前面i-1个数已经匹配过了,那么当协议书传过来时即可匹配,否则无法匹配
我让你让所有数匹配最少传多少圈(向上取整)

输入样例#1

5
1 5 8 4 3

输出样例#1

3

输入样例#2

10
11 8 5 7 1 6 2 3 4 10

输出样例#2

6

样例解释#1

第一轮:8
第二轮:5 4 3
第三轮:1

数据范围

1 ⩽ n ⩽ 8 × 1 0 5 1 ⩽ a i ⩽ 1 0 6 1\leqslant n \leqslant 8 \times 10^5\\1\leqslant a_i\leqslant 10^6 1n8×1051ai106

解题思路

如果直接暴力枚举会TLE
当匹配完值为 i i i的点后需要匹配值为 i + 1 i+1 i+1的点
那么可以按 a i a_i ai排序,这样得到匹配的数的顺序
v i v_i vi为当前数的初始位置
如果 v i > v i − 1 v_i>v_{i-1} vi>vi1那么不用多传一圈
否则要多传一圈

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n, ans;
struct node
{
	int v, s;
}a[800010];
bool cmp(node x, node y)
{
	return x.s > y.s;//按给出的值排序
}
int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d", &a[i].s);
		a[i].v = i;//记录初始位置
	}
	sort(a + 1, a + 1 + n, cmp);//排序
	for (int i = 2; i <= n; ++i)
		if (a[i].v < a[i - 1].v)//要多传一圈
			ans++;
	ans++;//不满一圈的
	printf("%d", ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值