长乐一中 CSP-S 2025 提高级模拟赛 Day2

中午午休没去然后下午翘了一节英语一节数学课打比赛,预估是 \(100+20+30+10=160\) 的结果挂到 \(80+0+10+0=90\),T1 数据范围 \(n \le 5000\) 看成 \(n \le 1000\) 结果数组开小,100pts -> 80pts,我是 /bangbangt

A. 大佬排队

首先可以从最矮的那个人开始考虑,队列里面还没放人,第一个人的左边有 \(a_1\) 个人比自己高,所以就要留出 \(a_1\) 个空位给这些高人站,然后自己站到 \(a_1+1\) 个位置上。

然后对于第 \(i(i>1)\) 矮的人,就不用考虑前面的人了(因为前面的人都比自己矮),前面要留出 \(a_i\) 个空位给高人站,自己站到 \(a_i+1\) 个空位上。

然后就得到了一个 \(O(n^2)\) 的做法:对于每一个人 \(a_i\),枚举队列的第 \(a_i+1\) 个空位然后把这个人丢进去。最后输出这个队列即可。

赛时数组开小喜提暴力分,糖丸了

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=5007;
int n,h[N],a[N];
inline bool check()
{
	for(int i=1;i<=n;i++)
	{
		int cnt=0;
		for(int j=1;j<i;j++) if(h[j]>h[i]) cnt++;
		if(cnt!=a[h[i]]) return 0;
	}
	return 1;
}
inline void brute()
{
	for(int i=1;i<=n;i++) h[i]=i;
	do
	{
		if(check())
		{
			for(int i=1;i<=n;i++) cout<<h[i]<<' ';
			return;
		}
	}while(next_permutation(h+1,h+n+1));
}
inline void ac100()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1,cnt=0;j<=n;j++)
		{
			if(h[j]==0) cnt++;
			if(cnt==a[i]+1)
			{
				h[j]=i;
				break;
			}
		}
	}
	for(int i=1;i<=n;i++) cout<<h[i]<<' ';
}
int main()
{
	freopen("line.in","r",stdin);
	freopen("line.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	ac100();
	return 0;
}
posted @ 2025-09-10 21:13  wwwidk1234  阅读(17)  评论(0)    收藏  举报