求助


考虑爆炸只会发生在相邻的两个炸弹,那么我们不妨把所有相邻的炸弹的信息放入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

相关推荐

一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务