求助


考虑爆炸只会发生在相邻的两个炸弹,那么我们不妨把所有相邻的炸弹的信息放入set,然后每次找到爆炸时间尽可能短的,然后把它们删除,删除以后呢?肯定要把与它两相连的删除掉在set里,然后呢,把爆炸后的左右相连的点合并放入set.就做完了.左右相连用链表维护.

不知道wa在哪里了...求大佬看看

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const double eps=1e-3;
struct sb{
	double w;
	int ida,idb;
};
bool operator<(sb A,sb B)
{
	if(A.w==B.w)
	{
		if(A.ida==B.ida)	return A.idb<B.idb;
		else				return A.ida<B.ida;
	}
	else return A.w<B.w;
}

int l[N],r[N];//维护这个点左/右边下标是哪个点 
bool ans[N]; 
vector<int>res;
struct nm{
	double x,v;
	int id;
}b[N];

bool cmp(nm A,nm B)
{
	return A.x<B.x;
}

double Time(nm A,nm B)
{
	if(A.v>=0&&B.v<0||A.v>0&&B.v<=0)
	{
		return (B.x-A.x)/(A.v-B.v);
	}
	else if(A.v<=0&&B.v>=0)	return 1e9;
	else
	{
		if(A.v<0&&B.v<0&&A.v<=B.v)	return 1e9;
		if(A.v>0&&B.v>0&&A.v<=B.v)	return 1e9;
		double V=fabs(A.v-B.v);
        if(V<=eps)    return 1e9;
		return (B.x-A.x)/V;
	}
}

void merge(int L,int R)
{
	r[L]=R;
	l[R]=L;
}


void run()
{
	//set 放三个元素一定是从左往右放
	int n;
	set<sb>s;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)	scanf("%lf",&b[i].x);
	for(int i=1;i<=n;i++)
	{
		scanf("%lf",&b[i].v);
		b[i].id=i;
	}
	sort(b+1,b+1+n,cmp);
	for(int i=1;i<=n;i++)
	{
		 if(i==1)
		 {
		 	l[b[i].id]=0;
		 	r[b[i].id]=b[i+1].id;
		 }
		 else if(i==n)
		 {
		 	l[b[i].id]=b[i-1].id;
		 	r[b[i].id]=n+1;
		 	s.insert({Time(b[i-1],b[i]),b[i-1].id,b[i].id});
		 }
		 else
		 {
		 	l[b[i].id]=b[i-1].id;
		 	r[b[i].id]=b[i+1].id;
		 	s.insert({Time(b[i-1],b[i]),b[i-1].id,b[i].id});
		 }
	}
	for(int i=1;i<=n/2;i++)
	{
		auto x=*s.begin();
		if(fabs(x.w-1e9)<=eps)	break;
		s.erase(x);
		if(l[x.ida]!=0)					s.erase({Time(b[l[x.ida]],b[x.ida]),l[x.ida],x.ida});
		if(r[x.idb]!=n+1)				s.erase({Time(b[x.idb],b[r[x.idb]]),x.idb,r[x.idb]});
		if(l[x.ida]!=0&&r[x.idb]!=n+1)	
        {
            s.insert({Time(b[l[x.ida]],b[r[x.idb]]),l[x.ida],r[x.idb]});
        }
        merge(l[x.ida],r[x.idb]);
	}
	for(auto x:s)
	{
		if(!ans[x.ida])	ans[x.ida]=true,res.push_back(x.ida);
		if(!ans[x.idb])	ans[x.idb]=true,res.push_back(x.idb);
	}
	printf("%d\n",(int)res.size());
	sort(res.begin(),res.end());
	for(int x:res)
	{
		printf("%d\n",x);
	}
}

int main()
{
	int T=1;
	//cin>>T;
	while(T--)
	{
		run();
	}
	return 0;
}
/*
5
1 3 5 7 9
-1 -2 -4 2 4

*/


全部评论
这题不能用链表吗,用set维护就过了
点赞 回复 分享
发布于 2022-04-05 00:29

相关推荐

专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务