NEUQ-ACM预备队必做题——第二周

洛谷P1007 独木桥

思路:

这题需要知道的一点就是当两个士兵相遇时,其实没有任何影响;因为彼此都是士兵,没有任何不同,相当于互相穿过了对方。知道了士兵相遇之后并不对结果产生影响之后,通过枚举每一个点,知道当前点的士兵(们)到达两边的最短时间和最长时间,然后找出能完成逃跑的最小与最大时间即可。

代码:

#include <iostream>
using namespace std;
const int N=5e3+10;
int l,n,a[N];
int main()
{
	cin>>l>>n;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		a[x]++;
	}
	int minl=0,maxl=0;
	for(int i=1;i<=l;i++)
	{
		if(a[i]==0)continue;
		int lt,ht;
		lt=a[i]+min(i-0,l+1-i)-1;
		minl=max(lt,minl);
		ht=a[i]+max(i-0,l+1-i)-1;
		maxl=max(ht,maxl);
	}
	cout<<minl<<' '<<maxl;
	return 0;
}

洛谷P1223 排队接水

思路:

自然很容易知道接水时间短的应该最先接水,这样总的接水时间就会最短,等待的时间也会最短,所以对所有人的接水时间进行一个排序(同时用结构体存一下他们的原本的坐标),最后将他们总的接水时间加在一起(除去最后一个,因为没人需要等他)除以人数即可得到答案。

代码:

#include <algorithm>
#include <iostream>
using namespace std;
const int N=1e6+10;
int n;
struct T
{
	int t,id;
	bool operator < (const T &w)const
	{
		return t<w.t;
	}
}t[N];
int main()
{
	cin>>n;
	double res=0;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		t[i]={x,i};
	}
	sort(t+1,t+n+1);
	for(int i=1;i<=n;i++)
	{
		if(i!=n)res+=t[i].t*(n-i);
		printf("%d ",t[i].id);
	}
	puts("");
	printf("%.2lf",res/n);
	return 0;
}

洛谷P1803 凌乱的yyy / 线段覆盖

思路:

给定一些区间,求最大不重合区间数,算是模板题吧。
对所有给定区间的右端点进行排序,然后通过比较下个区间的左端点和当前区间的右端点,即可判断(记得时时更新当前区间的右端点)。

代码:

#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e6+10;
struct Edge
{
	int l,r;
	bool operator < (const Edge &w)const
	{
		return r<w.r;
	}
}edge[N];
int n;
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int left,right;
		cin>>left>>right;
		edge[i]={left,right};
	}
	sort(edge,edge+n);
	int res=0;
	int ed=-1;
	for(int i=0;i<n;i++)
	{
		if(edge[i].l>=ed)
		{
			res++;
			ed=edge[i].r;
		}
	}
	cout<<res;
	return 0;
}

洛谷P1031 [NOIP2002 提高组] 均分纸牌

思路:

从第一堆开始,每次当前堆与平均数作比较,少了就从后面那一堆拿点过来,多了就给点给后面的。(因为只能和邻堆之间进行操作)

代码:

#include <iostream>
using namespace std;
const int N=110;
int a[N];
int main()
{
	int n,sum=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		sum+=a[i];
	}
	sum=sum/n;
	int res=0;
	for(int i=0;i<n-1;i++)
	{
		int mid=sum-a[i];
		if(mid!=0)
		{
			res++;
			a[i+1]-=mid;
		}
	}
	cout<<res;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值