晚会舞蹈 题解

题目来源:QZEZOJ

题目传送门

题目描述

晚会上有好多小伙伴,准备开始一场舞蹈。
舞蹈是2 个人一起跳的,而且是一男一女。
规定所有的人都站成了一排跳舞。
这一排人的顺序满足两点:
①对于任何一对舞伴,男生一定在女生的左边方向。
②任何一对舞伴之间,要么没有人,要么就有若干对舞伴。
其中女生知道自己左边有几个男生。
现在就请你再告诉这些女生,她们的舞伴距离她们多远(指包括那个男生,一共有多少男生夹在这对舞伴之间)。

输入

第一行为一个数N,表示参与的女生个数。
第二行N 个数,第i个数为Ai,表示从左往右数的第i个女生左边共有Ai个男生;

输出

输出共一行N个数,每两个整数之间用一个空格隔开,行末无空格。表示N 个女生与其舞伴的距离。

样例输入

6
4 5 6 6 6 6

样例输出

1 1 1 4 5 6

提示

对于30%的数据: 1N50
对于50%的数据: 1N2,000
对于100%的数据:1N500,0001AiAjN1i<jN);数据保证合法,不必验错。

题目解析

先来看一看样例解释:
在这里插入图片描述
这里菱形表示的是男生,三角形表示的是女生,一组舞伴用一条曲线连起来,这样答案就很显然了。

预处理

我们看一看输入的是什么:

第二行N个数,第i个数为Ai,表示从左往右数的第i个女生左边共有Ai个男生;

输入的数不方便操作,我们就可以把它转化成类似于上图的样子。
这里将输入的数组x转化为数组a.
我们用变量k来统计左端男生的个数,如果到达一定数量了,就放一个女生就可以了。这里用1来表示女生,2表示男生。
代码:

void pre(void){
for(i=j=k=1;i<=2*n;i++){
if(j==x[k]+1){
k++;
a[i]=1;//女生
}
else{
j++;
a[i]=2;//男生
}
}
return;
}

计算

预处理好之后,就开始计算了。
先看看数据,n500,000 ,比较大,O(N2)会炸掉,不能等出现女生在开始找,所以,我们可以用空间换时间,开一个栈,记录下男生的位置就可以了。这样可以实现O(N)的复杂度了。

memset(x,0,sizeof(x));
k=0;
for(int i=1;i<=2*n;i++){
if(a[i]==2){
k++;
x[k]=i;
}
else{
printf("%d ",(int)ceil((i-x[k])/2.0));
k--;
}
}

放一下你们最爱的AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn 5000039
using namespace std;
int x[maxn],a[maxn<<1];
int n,i,j,k;
void pre(void){
for(i=j=k=1;i<=2*n;i++){
if(j==x[k]+1){
k++;
a[i]=1;//女生
}
else{
j++;
a[i]=2;//男生
}
}
return;
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&x[i]);
pre();
memset(x,0,sizeof(x));
k=0;
for(int i=1;i<=2*n;i++){
if(a[i]==2){
k++;
x[k]=i;
}
else{
printf("%d ",(int)ceil((i-x[k])/2.0));
k--;
}
}
return 0;
}

完结撒花

posted @   jiangtaizhe001  阅读(78)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示