郑州大学“战役杯”第四次比赛题解

1 时空密接 

在抗击疫情的过程中,我们需要清楚确定密接,而感染者的整个运动过程中和他位置重合的人都将被当作密切接触者,现在就请你设计一个算法计算两个人的轨迹是否有时空密接。

为了简化问题我们把场景当成一个二维坐标系,每个人看作坐标系上的一个整数点,在每一个时刻会原地不动或向上下左右移动一格,我们认为两个人只要在某一时刻出现在了同一个网格中就是时空密接。

输入格式:

第一行包含五个用空格隔开的正整数x1​,y1​,x2​,y2​(−109≤x1​,y1​,x2​,y2​≤109),t(1≤t≤100),分别代表两个人在0时刻所处的位置,以及接下来的t时刻中的移动路径。

第二行和第三行都是一个长度为t的字符串,分别代表两人在每一时刻的移动轨迹,字符串由大写字母W,S,A,D,O组成,分别代表上下左右移动一格与停止不动,即坐标由(x,y)改变为(x,y+1),(x,y−1),(x−1,y),(x+1,y),(x,y)。

输出格式:

如果两人存在时空密接就输出'yes',否则则输出'no'(不含引号,且区分大小写)。

输入样例:

1 1 2 2 4
DDDO
DSDD

输出样例:

yes

样例解释

两人的坐标分别为:

(1,1)→(2,1)→(3,1)→(4,1)→(4,1)

(2,2)→(3,2)→(3,1)→(4,1)→(5,1)

因此两人在第2、3时刻在同一位置,属于时空密接。

源代码 

今天心态炸裂了家人们第一题因为特判WA了几次 

注意特判可能刚开始就有时空交际 

#include <iostream>
using namespace std;
int main()
{
	int x1,y1,x2,y2,t;
	cin>>x1>>y1>>x2>>y2>>t;
	string a,b;
	cin>>a>>b;
    int flag=0;
	for(int i = 0;i < t;i ++ )
	{
        if(x1==x2&&y1==y2)
		{
			flag=1;
			break;
		}
		switch(a[i])
		{
			case 'A':
				x1=x1-1;
				break;
			case 'W':
				y1=y1+1;
				break;
			case 'D':
				x1=x1+1;
				break;
			case 'S':
				y1=y1-1;
				break;
			case 'O':
				break;
		}
		switch(b[i])
		{
			case 'A':
				x2=x2-1;
				break;
			case 'W':
				y2=y2+1;
				break;
			case 'D':
				x2=x2+1;
				break;
			case 'S':
				y2=y2-1;
				break;
			case 'O':
				break;
		}
	} 
	if(flag==0)cout<<"no";
    else if(flag==1)cout<<"yes";
	return 0;
}

 2 今晚吃鸡

777777777Plus和SW2000正在游玩一款fps(第一人称射击类)游戏,在游戏中777777777Plus和SW2000需要瞄准射击,当系统判定到击中头部,身体,和四肢时会造成不同的伤害。当击中头部时,会造成100点伤害;当击中胸背部时,会造成30点伤害,当击中四肢时,会造成10点伤害。当血量小于等于0时,游戏结束,血量不为0的一方获胜。

同时该游戏有防具设计,包括头盔(保护头部)和护甲(保护胸背部)。当玩家穿着防具时,对该部位的攻击会由扣除血量改为扣除防具的耐久度。当防具耐久度降低到0时将会破碎失去伤害抵挡效果。

换言之,如果防具当前耐久为x,收到的攻击为y,当x>y时,防具的耐久变为x−y,不会破碎。当x≤y时,防具会破碎,且此次攻击不再扣除玩家血量。

现在,给出777777777Plus和SW2000游戏的记录,你能否算出是谁在游戏中获胜了?

输入格式:

第一行输入三个整数a1,b1,c1(1≤a1≤100,0≤b1,c1≤100),分别表示777777777Plus的剩余血量,护甲耐久度,头盔耐久度。

第二行输入三个整数a2,b2,c2(1≤a2≤100,0≤b2,c2≤100),分别表示SW2000的剩余血量,护甲耐久度,头盔耐久度。

第三行一个n(1≤n≤1000)代表游戏记录条数。

其后n行,每行两个字符串s,t。其中当s是"777777777Plus"(不带引号)时,代表777777777Plus受到了攻击,反之当s是"SW2000"(不带引号)时,代表SW2000受到了攻击。
当t是"head"(不带引号)时,代表头部受到攻击,当t是"body"(不带引号)时,代表胸背部受到攻击,当t是"limbs"(不带引号)时,代表四肢受到攻击。

数据保证不存在玩家血量小于等于0后继续攻击的情况。

输出格式:

输出一行一个字符串,"777777777Plus"或者"SW2000",代表获胜玩家。输出时不需要带引号。

输入样例:

1 1 1
100 0 0
4
777777777Plus head
SW2000 body
777777777Plus body
SW2000 head

输出样例:

777777777Plus

源代码

心态继续炸裂b错写成aWA了十几次 

#include <iostream>
using namespace std;
int main()
{
	//一定要注意讨论的时候a和b的区别,我wa了快十次一看是b错写成了a 
	int a1,b1,c1;
	cin>>a1>>b1>>c1;
	int a2,b2,c2;
	cin>>a2>>b2>>c2;
	int t;
	cin>>t;
	string human;
	string idx;
	while(t--)
	{
		//开头无特判 
		cin>>human>>idx;
		if(human=="777777777Plus")
		{
			//只要装备不烂就疯狂抗 
			if(idx=="head")//爆头 
			{
				if(c1>0)c1-=100;
				else a1-=100;
			} 
			else if(idx=="body")//打腰子 
			{
				if(b1>0)b1-=30;
				else a1-=30;
			}
			else a1-=10;//打胳膊腿 
		} 
		else
		{
			//只要装备不烂就疯狂抗
			if(idx=="head")//爆头 
			{
				if(c2>0)c2-=100;
				else a2-=100;
			} 
			else if(idx=="body")//打腰子
			{
				if(b2>0)b2-=30;
				else a2-=30;
			} 
			else a2-=10;//打胳膊腿
		}
		//哪个大怨种被射死了活着的就是赢家 
		if(a1<=0)
		{
			cout<<"SW2000";
			break;
		} 
		else if(a2<=0)
		{
			cout<<"777777777Plus";
			break;
		}
	}
	return 0;
}

 3 核酸排队

在疫情到来的时候,做核酸成了大多数同学们的日常。做核酸也是需要时间的,而且在一个核酸检测点做核酸的人数往往很多,等待时间有时候会比较长。

在一个核酸检测点基本都安排有两个队列(默认两个队列的长度都为无限大):

  • 扫码队列:在该队列中,我们等待志愿者扫码录入核酸检测信息,志愿者每扫一个同学的码需要x单位时间。
  • 核酸队列:在该队列中,我们等待医生为我们做核酸,每个同学做核酸需要y单位时间。

一位同学做核酸的过程可以认为是先到达扫码队列等待志愿者扫码录入信息,录入信息之后到达核酸队列等待做核酸。一个志愿者一次只能处理一个同学的扫码,一个医生一次只能对一位同学进行核酸检测。

小王深深体会到了医生们的辛苦,他希望通过计算同学们等待做核酸的时间,以此平衡好同学们做核酸、学习和生活的时间。

假设核酸检测点只有一个志愿者和一个医生。已知有n个同学,第i个同学到达核酸检测点(即到达扫码队列)的时间为ti​(数据保证到达扫码队列的时间是升序的,且各不相同),求编程计算第i个同学做核酸耗费的时间wi​。

本题认为耗费时间为从到达扫码队列到完成做核酸的时间

输入格式:

一共三行。

第一行为一个整数n(1≤n≤105)。

第二行为两个整数x,y(1≤x,y≤105)

第三行为n个整数t1​,t2​,t3​,...,tn−1​,tn​(1≤ti​≤109)

输出格式:

在一行输出n个核酸检测等待时间w1​,w2​,w3​,...,wn​

输入样例:

3
2 3
3 5 6

输出样例:

在这里给出相应的输出。例如:

5 6 8

源代码

数列这东西我不太熟还是参考的一位大佬的思路肝出来了 

#include<iostream>
#include<queue>//数列 
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
queue<PII> A,B;//创建数对队列 
int main()
{
	//首先数据较大,开优化 
	ios::sync_with_stdio(false);
	cin.tie(0);
	//进行数据输入 
	ll n;
    cin>>n;
	ll x,y;
	cin>>x>>y;
    while(n--)
    {
    	//对于每个同学到达的时间进行输入 
    	ll num;
        cin>>num;
        A.push({num,0});//存的first是该同学到达的时间,second是该同学等待的时间 
    }
    ll del=A.front().first;//默认偏移量为首个同学到达的时间 
    //首先对于A数对数列进行处理,也就是扫码队列 
    while(!A.empty())//当该队列全部成员为处理完毕时 
    {
        if (del>=A.front().first)//如果偏移量比该同学的来到时间长也就是该同学要等待扫码的情况 
        {
            del+=x;//偏移量加上扫码时间即为来到核酸队列的时间 
            auto t = A.front();//定义临时数对 
            t.second = del-t.first;//second存的是该学生等待的时间和扫码的时间的和也就是偏移量与该同学到来时间的差值 
            t.first = del;//first为该同学来到核酸队列的时间 
            B.push(t);//推入核酸队列 
            A.pop();//弹出扫码队列 
        }
        else//如果偏移量比该同学来到的时间短也就是该同学一来就能够扫码,那么等待时间为0 
        {
            auto t=A.front();//定义临时数对 
            del=t.first+x;//该同学来到扫码队列的时间加上扫码的时间为来到核酸队列的时间 
            t.second=x;//second存的是该学生所用的时间之和在此仅仅为扫码的时间 
            t.first=del;//该学生来到核酸队列的时间 
            B.push(t);//推入 
            A.pop();//弹出 
        }
    }
    del = B.front().first;//偏移量更新为首位同学来到核酸队列的时间 
    while (!B.empty())//如果队列中的数对未处理完毕 
    {
        if(del>=B.front().first)//如果偏移量大于该同学来到核酸队列的时间也就等价于该同学要等待一段时间 
        {
            del+=y;//做完核酸之后+偏移量的和 
            auto t=B.front();//定义临时数对 
            B.pop();//弹出 
            cout<<t.second+(del-t.first);//输出second(扫码所需要的总时间)加上更新完的偏移量减去first即为核酸用的总时间 
            if (!B.empty())cout<< " ";//如果此时队列还有元素注意输出一个空格 
        }
        else//此时偏移量小于该同学来到核酸队列的时间也就是等待时间为0 
        {
            auto t = B.front();//定义临时数对 
            B.pop();//弹出 
            del=t.first+y;//偏移量更新 
            cout<<t.second+y;//该同学所用的总时间等于second(扫码所需要的总时间)+y(做核算所需要的总时间) 
            if(!B.empty())cout<<" ";//如果此时队列还有元素注意输出一个空格 
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/couchpotatoshy/article/details/124740534
今日推荐