CodeForces - 1353D Constructing the Array(bfs)

题目链接:点击查看

题目大意:给出一个长度为 n ,初始时全部为 0 的数组 a ,后续进行 n 次操作,每次操作找到最长的连续 0 ,如果有多个则选择位置最靠左边的,将这组连续 0 的,最中间位置的数赋值为 i ,i 为第 i 次操作,输出最后的数列

题目分析:一开始没什么思路,用线段树区间合并暴力模拟的,果不其然 TLE 了,其实自己手算模拟几次就会发现,每个位置至多会被遍历到一次,且是按照深度扩展的,所以我们可以用 bfs + 优先队列 不断扩展就好了,具体实现可以看代码

代码:
 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
 
typedef long long LL;
 
typedef unsigned long long ull;
 
const int inf=0x3f3f3f3f;
 
const int N=2e5+100;

int ans[N],pos;

struct Node
{
	int l,r;
	Node(int l,int r):l(l),r(r){}
	bool operator<(const Node& t)const
	{
		if(r-l+1!=t.r-t.l+1)
			return r-l+1t.l;
	}
};

void bfs(int l,int r)
{
	priority_queueq;
	q.push(Node(l,r));
	while(q.size())
	{
		Node cur=q.top();
		q.pop();
		l=cur.l;
		r=cur.r;
		int mid=l+r>>1;
		ans[mid]=++pos;
		if(l==r)
			continue;
		if(mid+1<=r)
			q.push(Node(mid+1,r));
		if(l<=mid-1)
			q.push(Node(l,mid-1));
	}
}

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		int n;
		scanf("%d",&n);
		pos=0;
		bfs(1,n);
		for(int i=1;i<=n;i++)
			printf("%d ",ans[i]);
		puts("");
	}








    return 0;
}

 

你可能感兴趣的:(CodeForces上分,bfs)