2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017)

2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017)

H

题意:

有K个人进行跑步比赛。有两条要求:
1,所有人,两两之间的距离不得低于B否则会迷路
2,每个人不希望他人靠近自己Ai之内的距离
给出了p个路径点di,以及每个人现在所处的位置
求每次让谁跑到下一个路径点,不可能输出impossible

思路:

用队列维护这样一个数据结构:
结构内存储区间内当前状态下可以移动的人分别有哪些。

每次从队列里面取出一个人进行移动,此时队伍状态发生变化,显然,这只对取出的那个人的前一个人、后一个人,还有他本身产生影响,所以,动态维护的时候只需要判断这三个人是否符合条件,然后加进去就好了。要注意的是,数据结构内不允许一个人重复出现,所以需要用vis数组判重。
其他细节见代码

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline long long read()
{
	long long kk=0,f=1;
	char cc=getchar();
	while(cc<'0'||cc>'9'){if(cc=='-')f=-1;cc=getchar();}
	while(cc>='0'&&cc<='9'){kk=(kk<<1)+(kk<<3)+cc-'0';cc=getchar();}
	return kk*f;
}
int mark[1011];int B,P,K;
struct zj
{
	int pos,dis,o;
};
zj an[1011];
bool cmp(zj a,zj b)
{
	return a.pos<b.pos;
}
queue<int>q;int ans[1000011],co=0;bool vis[1000011];
bool check(int i)
{
	int now,per,next;
	now=an[i].pos;per=an[i-1].pos;next=an[i+1].pos;
    if(now>=P)return 0;
    if(i>1&&mark[now+1]-mark[per]>B)return 0;//往前走后不能让后面的人落下你太多 ,最后面的人没有后面 
    if(i<K&&next!=P)//最前面的人没有前面 
	if(mark[next]-mark[now+1]<max(an[i].dis,an[i+1].dis))return 0;//还要与前面的人保持距离 
    return 1;
}
int main()
{
	B=read();P=read();
	for(int i=1;i<=P;++i)mark[i]=read();
	sort(mark+1,mark+1+P);//按照初始位置排序 
	K=read();
	for(int i=1;i<=K;++i)
	{
		an[i].dis=read();an[i].o=i;
		an[i].pos=read();
	}
	sort(an+1,an+1+K,cmp);
	for(int i=1;i<=K;++i)
	if(check(i))
	{
		if(!vis[i])q.push(i);vis[i]=1;//vis记录是否再队列中 
	}
	int tot=0;
	while(!q.empty())//移动每一个可移动的,同时维护他以及他前后的人是否可以移动 
	{
		int now1=q.front();q.pop();ans[++co]=now1;//ans记录每次移动的方案 
		an[now1].pos++;
		vis[now1]=0;
		if(an[now1].pos==P)K--;//如果有人移动到终点,在区间内的人就少一,领队改变 
		if(K<=1)break;//考虑最后只剩下一个人的情况,接下 
		if(check(now1)&&!vis[now1])
		{
			q.push(now1);vis[now1]=1;
		}
		if(now1>1)
		if(check(now1-1)&&!vis[now1-1])
		{
			q.push(now1-1);vis[now1-1]=1;
		}
		if(now1<K)
		if(check(now1+1)&&!vis[now1+1])
		{
			q.push(now1+1);vis[now1+1]=1;
		}
		
	}
	if(K>1)printf("impossible");//如果有不止一个人在区间内,但是维护的队列里没有元素,说明陷入死局 
	else 
	{
		for(int i=1;i<=co;++i)printf("%d ",ans[i]);
		while(++an[1].pos<=P)printf("%d ",an[1].o);//接上,一个人到达终点 
	}
	return 0;
}

I

题意:

给出n个Hi ,1个T。求出T%Hi最小的那个Hi

思路:

循环一遍即可。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline long long read()
{
	long long kk=0,f=1;
	char cc=getchar();
	while(cc<'0'||cc>'9'){if(cc=='-')f=-1;cc=getchar();}
	while(cc>='0'&&cc<='9'){kk=(kk<<1)+(kk<<3)+cc-'0';cc=getchar();}
	return kk*f;
}
LL a[20];
int main()
{
	LL n=read();
    for (int i=1;i<=n;i++)a[i]=read();
    LL sum=read();
    LL asd=a[1];
    for (int i=2;i<=n;i++)if(sum%a[i]<sum%asd)asd=a[i];
    printf("%d\n",asd);
}

j

题意:给出n个数,按照表格对应音符的长度,求曲子的总长度

思路:

可以看到,输入的数和音符的长度是倒数关系,用double存好后相加就好。要注意,输出一定要按6位输出…我就是这里没看到写炸了3次

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline long long read()
{
	long long kk=0,f=1;
	char cc=getchar();
	while(cc<'0'||cc>'9'){if(cc=='-')f=-1;cc=getchar();}
	while(cc>='0'&&cc<='9'){kk=(kk<<1)+(kk<<3)+cc-'0';cc=getchar();}
	return kk*f;
}
int main()
{
	LL n=read();
	double k,sum=0;
	for(int i=1;i<=n;++i)
	{
		double kk=(double)(read());if(kk==0)k=2;
		else k=((double)(1)/kk);
		sum+=k;
	 } 
	 printf("%.6llf",sum);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值