NEUQ-ACM 必做题 week2

P1007 独木桥

1.当士兵相遇时掉头,可以看作是穿过彼此(灵魂交换);

2.最小值即为士兵们最快返回时间的最大值;

3.最大值即为士兵们最慢返回的时间的最大值;

#include <bits/stdc++.h>
using namespace std;
int l,n,a,t,x,y;
int minn=0,maxn=0;
int main(){
	cin>>l>>n;
	for (int i=1;i<=n;i++){
		cin>>a;
		x=a-0; //找出往两边方向的时间
		y=l-a+1;
		if (x<y){ //排序
			t=x;
			x=y;
			y=t;
		}
		if(x>maxn) maxn=x; //找出最慢返回时间的最大值
		if(y>minn) minn=y; //找出最快返回时间的最大值
	}
	cout<<minn<<" "<<maxn;
	return 0;
} 

P1223 排队接水

1.想使等待时间最短,尽量使打水时间最短的先打水,如第一个人打水时间1min,则后面9人共等待1*9min,如果打水时间1000min,则后面9人共等待1000*9min;

2.第i个人打水时,后面还有(n-i)个人,共需等待(n-i)*Ti

#include <bits/stdc++.h>
using namespace std;
struct paidui{ //结构体记录打水时间和位置
    int value;
    int p;
} a[1010];
bool cmp(const paidui &a,const paidui &b){
	if(a.value==b.value) return a.p<b.p;
	else
	   return a.value<b.value;
}
int main(){
	int n;
	double sum=0;
	cin>>n;
	for(int i=1;i<=n;i++){ //初始化
		cin>>a[i].value;
		a[i].p=i;
	}
	sort(a+1,a+1+n,cmp); //按照打水时间排序
	for (int i=1;i<=n;i++){ 
		cout<<a[i].p<<" ";  //输出位置
		sum+=(n-i)*a[i].value; 
	} 
	cout<<endl;
	printf("%.2lf",sum/n);
	return 0;
} 

P1803 凌乱的yyy / 线段覆盖

1.按照结束时间排序,再判断在此场比赛结束后最近时间的比赛立刻参加

#include <bits/stdc++.h>
using namespace std;
struct p{
	int a; //a储存开始时间
	int b; //b储存结束时间
}pp[1000005];
bool cmp(p x,p y){
	return x.b<y.b;
}
int main(){
	int n,t,ans=1;
	cin>>n;
	for (int i=1;i<=n;i++){
		cin>>pp[i].a>>pp[i].b;
	}
	sort(pp+1,pp+1+n,cmp); //按照结束时间排序
	t=pp[1].b;
	for (int i=2;i<=n;i++){
		if(pp[i].a>=t){  //若下一场比赛开始时间在上一场比赛结束时间之后
			ans++;  //参赛
			t=pp[i].b; //更新结束时间
		}
	}
	cout<<ans;
	return 0;
}

P1031 [NOIP2002 提高组] 均分纸牌

1.负数向右移动,相当与右边的一堆牌向左移

#include <bits/stdc++.h>
using namespace std;
int a[10010],sum,j,ave,n,step,i=1;
int main(){
	cin>>n;
	for (i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
	}
	ave=sum/n; //算出平均数,即每堆最后的牌数
	for (i=1;i<=n;i++){
		a[i]=a[i]-ave; //算出差值,即还差几张,可以正负
	}
	i=1; j=n;
	while(a[i]==0 &&i<n) i++; //过滤掉最左右端已经满足条件
	while(a[j]==0 &&j>1) j-- ;
	while(i<n){ 
		a[i+1]+=a[i]; //把牌向右移
		a[i]=0;
		step++;
		i++;    
		while(a[i]==0&&i<n) i++; //移牌后满足牌数的一堆跳过
	}
	cout<<step;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值