【解题报告】【】交谊舞

                                      Title:交谊舞

Description

描述 明显……交谊舞是2个人跳的,而且一男一女 -__-||||。 由于交谊舞之前的节目安排,所有的表演者都站成了一排。这一排人的顺序满足2点:

  • 对于一对舞伴男生站在女生的左边。
  • 任何一对舞伴之间,要么没有人,要么就有若干对舞伴。

排得过于整齐导致那些要表演交谊舞的人都没办法看到自己的舞伴,怎么办类……. 所幸的是,SDFZ的女生比男生聪明得多。她们知道自己左边有几个男生。 现在就请你再告诉这些女生,她们的舞伴距离她们多远(即包括那个男生,一共有多少男生夹在他们之间)。

Input Format

输入格式

第一行为一个数n,表示参与跳交谊舞的女生个数。

第二行n个数,从左到右表示这n个女生左边分别有多少个男生。

Output Format

输出格式

一排n个数,行末无空格。表示n个女生与其舞伴的距离。

Sample Input

6
4 5 6 6 6 6

Sample Output

1 1 1 4 5 6

Hint

各个测试点1s

n<=1500,结果小于2^31-1

Analysis

算法:贪心+模拟

简析:女生选舞伴的原则,往左找第一个未被挑选的男生(若找非第一个未被挑选的男生,则之间必然经过第一个没被挑选的男生,不符合中间是成对舞伴的条件)

做法:s[i]记录到i女生在所有人中的编号
           man[i]记录i女生左边共有多少男生
           c[i]记录可供选择的男生区间,并保证c[i]递增,c[i].l,c[i].r为区间的左右边界,c[i].now为该区间可取的为c[i].l-->c[i].now
           枚举1-n个女生,若man[i]>man[i-1]说明多出了一个可供选择的男生区间,则加入c[i](加入的是男生在全部人中的编号)
           接着输出c[tot]中可供选择的男生,若该区间已被取完则tot--,直到找到可供选择的区间。
 
注意:c[i]记录的是男生在全部人中的编号,所以计算起来较复杂
 
复杂度:O(n^2)

Code

//by king QZqz 
#include
#include
#include
const int N=1600;
struct data{
	int l,r,now;
}c[N];
int man[N],s[N],n,lastman,tot;
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&man[i]);
		s[i]=s[i-1]+1+man[i]-man[i-1];
	}//man[i]-man[i-1]是在i和i-1之间的男生,+s[i-1]+1,就是到i女生在所有人中的编号 
	man[0]=0;
	for (int i=1;i<=n;i++)
	{
		if (man[i]>man[i-1])//多了可供选择的男生区间 
		{
			tot++;
			c[tot].l=man[i-1]+i;//左边界,男生+女生得到该区间男生的初始编号 
			c[tot].now=c[tot].r=c[tot].l+man[i]-man[i-1]-1;
			//右区间为左区间加上i和i-1之间的男生(新增男生人数)-1(扣去i女生本身) 
		}
	    while (c[tot].now=1) tot--;//找到一个可供选择c[tot].now(舞伴的编号)
	    int j=1;
	    while (s[j]=1) tot--;
	}
	return 0;
}



你可能感兴趣的:(【解题报告】【】交谊舞)