2022 Robocom世界机器人开发者大赛 CAIP编程赛道 本科组-决赛 挨打记录+题解

这篇具有很好参考价值的文章主要介绍了2022 Robocom世界机器人开发者大赛 CAIP编程赛道 本科组-决赛 挨打记录+题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2022 Robocom CAIP编程赛道 决赛挨打记录+题解

打完决赛本菜鸡可以退役辣!并不是很开心因为上学期的考试还没复习完,哭了TAT

由于PTA还没有上架题目,只能描述个大概,各位姥爷见谅

u1

给定一串时间序列,表示在什么时刻按了开关。在按下之后的15秒后会变绿灯,持续30秒,如果在持续期间有再次被按下则延长15秒,只能被延长一次,请输出所有的绿灯时间段

这第一题是真的恶心,我写它就写了快半个小时,蚌埠住了

大致思路就是模拟,如果灯没被按就变一下flag,然后维护一下st和ed两个时间段,如果这中间又被按了一下就ed+15这样子

#include<bits/stdc++.h>
using namespace std;

const int N=1010;

int n;
int a[N];

int main()
{
	cin>>n;
	for (int i=1;i<=n;i++)	cin>>a[i];	
	a[n+1]=0x3f3f3f3f;	//让最后一个一定大于ed 防止特判 
	bool flag=false,add=false;	//false代表没被按 true代表被按了
	int st=0,ed=0; 
	for (int i=1;i<=n+1;i++)
	{
		if (!flag)	//没被按 
		{
			flag=true;
			st=a[i]+15;ed=a[i]+15+30-1;
		}
		else
		{
			if (a[i]<st)	continue;
			if (a[i]>ed)	
			{
				flag=false;add=false;
				cout<<st<<" "<<ed<<endl;
				i--;continue;
			}
			if (!add)
			{
				add=true;
				ed+=15;
			}
		}
	} 
	return 0;
} 

u2

给定一个5*5的棋盘,给定一个终点,有四只小怪,分别在棋盘的上下左右四个边界处,处于r1、r2、c1、c2四个行/列,还给定这四只小怪移动的距离,你要做的操作如下:

  1. 找到一个起始点
  2. 东西方向的小怪移动他们的距离,然后四只小怪一起攻击,攻击方式为小怪所在的本行/本列
  3. 你从起始点移动d1距离到第二个点
  4. 南北方向的小怪移动他们的距离,然后四只小怪一起攻击
  5. 你从第二个点移动d2距离到终点

要求每次移动到的点都不能被攻击,求合法的位置选择的具体方案

这题也是离了大谱,我看错题看错了两次,第一次以为移动的距离是只能往一个方向移动d1、d2的距离,第二次以为是小怪第一次不动,第二次东西南北一起动…他喵的

这个题可以反着推,从终点开始找,看看哪些点可以从终点走d2步到达,然后判断是否合法,再找哪些点可以从这个点走d1步到达且合法即可

不过问题是像俺这种解法是有可能重复的,由于unique函数不能用在结构体上(可能重载一下运算符可以,但我不会),所以写了个比较笨的去重,我感觉pair嵌套大礼包也是可以写的

#include<bits/stdc++.h>
using namespace std;

const int N=5;

int c1,c2,r1,r2;
int a[N];
int edx,edy,d1,d2;

struct Node{
	int a,b,c,d;
	friend bool operator<(Node x,Node y)
	{
		if (x.a!=y.a)	return x.a<y.a;
		if (x.b!=y.b)	return x.b<y.b;
		if (x.c!=y.c)	return x.c<y.c;
		if (x.d!=y.d)	return x.d<y.d;	
	}
};

int dx[]={1,1,-1,-1},dy[]={1,-1,1,-1};

bool equal(Node x,Node y)
{
	if (x.a==y.a && x.b==y.b && x.c==y.c && x.d==y.d)	return true;
	return false;
}

int main()
{
	cin>>c1>>c2>>r1>>r2;
	for (int i=1;i<=4;i++)	cin>>a[i];	
	cin>>edx>>edy>>d1>>d2;
	
	vector<Node> ans;
	for (int i=0;i<=d2;i++)
	{
		int dx1=i,dy1=d2-i;
		for (int k=0;k<4;k++)
		{
			int nx1=edx+dx1*dx[k],ny1=edy+dy1*dy[k];		
			if (nx1<1 || nx1>5 || ny1<1 || ny1>5)	continue;
			if (nx1==r1-a[3] || nx1==r2+a[4] || ny1==c1+a[1] || ny1==c2-a[2])	continue;					
			for (int j=0;j<=d1;j++)
			{
				int dx2=j,dy2=d1-j;
				for (int l=0;l<4;l++)
				{
					int nx2=nx1+dx2*dx[l],ny2=ny1+dy2*dy[l];								
					if (nx2<1 || nx2>5 || ny2<1 || ny2>5)	continue;
					if (nx2==r1-a[3] || nx2==r2+a[4] || ny2==c1 || ny2==c2)	continue;							
					ans.push_back({nx2,ny2,nx1,ny1});							
				}	
			}			
		}		
	}
	
	sort(ans.begin(),ans.end());
	for (int i=0;i<ans.size();i++)
		if (!i || (i && !equal(ans[i],ans[i-1])))
			cout<<ans[i].a<<" "<<ans[i].b<<" "<<ans[i].c<<" "<<ans[i].d<<endl;
		
	return 0;
} 

u3

给定一个图有n个点,m条边,每条边的长度都为1,然后给定你起点S和终点T,同时给定你是在K个人中的第p个。给定所有点的权值,规定路径上的第1个点分给第1个人,第p个点分给第p个人,第p+1个点分给第1个人…问在保证路径最短的前提下,你最后能获得的最大权值和是多少?

这题乍一看像最短路,结果仔细想了一下重点在边长全为1上,那也就是说对于给定的起点和终点,中间如果存在两条路线可走,那么这两条路线上对应的点到起点的距离一定是相等的,那么这个问题其实就等价成了对于给定的起点和终点,途中第p+n*k(n>=0)中的点的权值之和最大是多少

那我们可以先bfs一遍求出来所有点的距离,然后再bfs一遍求出来价值之和即可

#include<bits/stdc++.h>
using namespace std;

const int N=100010,M=2*N;

int n,m,k,p;
int a[N];
int h[N],e[M],ne[M],idx;
int S,T;

int dist[N],val[N];
bool st[N];

void add(int a,int b)
{
	e[idx]=b;ne[idx]=h[a];h[a]=idx++;
}

int main()
{
	cin>>n>>m>>k>>p;
	
	for (int i=1;i<=n;i++)	cin>>a[i];
	
	memset(h,-1,sizeof(h));
	while(m--)
	{
		int a,b;cin>>a>>b;
		add(a,b);add(b,a);
	}
	
	cin>>S>>T;
	
	memset(dist,0x3f,sizeof(dist));
	
	queue<int> q;
	q.push(S);
	st[S]=true;dist[S]=1;
	
	while(!q.empty())
	{
		int t=q.front();q.pop();		
		for (int i=h[t];~i;i=ne[i])
		{
			int j=e[i];
			if (dist[j]>dist[t]+1)
			{
				dist[j]=dist[t]+1;
				q.push(j);
			}
		}
	}

	memset(val,-0x3f,sizeof(val));
	memset(st,0,sizeof(st));
	q.push(S);
	st[S]=true;val[S]=0;
	
	while(!q.empty())
	{
		int t=q.front();q.pop();
		
		if (dist[t]>=p && (dist[t]-p)%k==0)
		{
			val[t]+=a[t];
		}
		
		if (t==T)	break;
		if (dist[t]>=dist[T])	continue;		
				
		for (int i=h[t];~i;i=ne[i])
		{
			int j=e[i];
			if (dist[j]>dist[t] && val[j]<val[t])
				val[j]=val[t];
			if (!st[j])
			{
				
				st[j]=true;
				q.push(j);
			}
		}	
	}

	cout<<val[T];
	return 0;
}

需要注意的是,第二遍bfs我们一定要用dist[t]小于dist[T]的点去更新,因为其实是有可能出现dist[t]==dist[T],但是它先进入队列,并且和T有一条边,就把T的结果给更新了,然而这种是不合法的,因为这两个点距离相等,且和终点之间有一条边,那么从它走到T一定不是最短路径了

从下面的题开始我就开始瞎写了

u4

题目大意是给定两个数组,问你最少需要多少步操作可以把数组一变成数组二,并且要求给出对第一个数组的操作:

  • 如果当前数字不变,输出2
  • 如果当前数字被删除,输出0
  • 如果当前数字前或后被添加了一个数字,输出3
  • 如果当前数字被改变,输出1

没什么好说,照着编辑距离瞎写的,结束2分钟交了一发举然骗到了17分,绝了

这题听说只管操作1和2打暴力能拿20分,tm比我凹了半天的解得分还高,我是真的会谢

#include<bits/stdc++.h>
using namespace std;

const int N=1010;

int a[N],b[N];
int lena,lenb;

int f[N][N];
string ans[N][N];

int main()
{
	int t=0;
	while(t!=-1)
	{
		cin>>t;
		a[++lena]=t;
	}
	
	t=0;
	while(t!=-1)
	{
		cin>>t;
		b[++lenb]=t;
	}
	
	memset(f,0x3f,sizeof(f));
	
	for (int i=0;i<=lena;i++)
	{
		f[i][0]=i;
		if (!i)
			ans[i][0]="";
		else 
			ans[i][0]=ans[i-1][0]+"3";
	}
	
	for (int i=0;i<=lenb;i++)
	{
		f[0][i]=i;
		if (!i)
			ans[0][i]="";
		else
			ans[0][i]=ans[0][i-1]+"3";
	}
	
	
	for (int i=1;i<=lena;i++)
		for (int j=1;j<=lenb;j++)
		{
			f[i][j]=min(f[i][j],f[i-1][j]+1);
			
			if (a[i]==b[j])
				f[i][j]=min(f[i][j],f[i-1][j-1]);
			else 
				f[i][j]=min(f[i][j],f[i-1][j-1]+1);
				
			if (f[i][j]==f[i-1][j]+1)
			{
				if (i>j)	ans[i][j]=ans[i-1][j]+"0";
				else ans[i][j]=ans[i-1][j]+"3";
			}
			else if (f[i][j]==f[i-1][j-1])
			{
				ans[i][j]=ans[i-1][j-1]+"2";
			}
			else if (f[i][j]==f[i-1][j-1]+1)
			{
				ans[i][j]=ans[i-1][j-1]+"1"; 
			}			
		}
	
	cout<<f[lena][lenb]<<endl;
	cout<<ans[lena][lenb];
	return 0;
}

u5

给定一棵树,和所有点的种类,问你有多少个三元组,这三个点之间的最短距离两两相同,且这三个点的种类都不同

没什么好说,一点思路都没有,floyd嗯跑拿了17分,结束前20分钟的时候在想是不是可以floyd换bfs,后来一想后面枚举的部分不会优化,那总的时间复杂度还是O(n^3),没区别啊

结果赛后有人告诉我floyd换bfs直接拿满了,我当场怀疑人生

#include<bits/stdc++.h>
using namespace std;

const int N=2010;
typedef pair<int,pair<int,int>> PIII;

int n;
int g[N][N];
int t[N];

int main()
{
	cin>>n;
	memset(g,0x3f,sizeof(g));
	
	for (int i=1;i<=n-1;i++)
	{
		int a,b;cin>>a>>b;
		g[a][b]=g[b][a]=1;
	}
	
	for (int i=1;i<=n;i++)
		cin>>t[i];
	
	for (int k=1;k<=n;k++)
		for (int i=1;i<=n;i++)
			for (int j=1;j<=n;j++)
				g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
				
	vector<PIII> ans;
	
	for (int i=1;i<=n;i++)
		for (int j=i+1;j<=n;j++)
			for (int k=j+1;k<=n;k++)
			{
				if (g[i][j]==g[j][k] && g[i][j]==g[i][k])
				{
					if (t[i]!=t[j] && t[i]!=t[k] && t[j]!=t[k])
					{
						ans.push_back({i,{j,k}});
					}
				}
			}
	
	cout<<ans.size();
	return 0;
}

总结

总的来说还算凑合,因为只需要有分就能拿奖,打得很放松,最后交的一发也送我拿了国一(应该吧?),94分摸了文章来源地址https://www.toymoban.com/news/detail-590424.html

到了这里,关于2022 Robocom世界机器人开发者大赛 CAIP编程赛道 本科组-决赛 挨打记录+题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2022 RoboCom 世界机器人开发者大赛-本科组(国赛)R4,R5题解

    就是给你一堆操作修改上面的数组让他变成下面数组,输出最小修改次数和方案 一眼dp,跑一遍dp记录方案数即可; dp[i][j]表示从左往右修改,第一个数组的i位等于第二个数组的j位的最小修改方案. c++能过代码 输入样例 输出样例 思路 先lca搞出来任意两点之间的距离。然后按

    2024年02月12日
    浏览(57)
  • 2022 Robocom世界机器人开发者大赛 CAIP编程赛道 本科组-决赛 挨打记录+题解

    打完决赛本菜鸡可以退役辣!并不是很开心因为上学期的考试还没复习完,哭了TAT 由于PTA还没有上架题目,只能描述个大概,各位姥爷见谅 给定一串时间序列,表示在什么时刻按了开关。在按下之后的15秒后会变绿灯,持续30秒,如果在持续期间有再次被按下则延长15秒,只

    2024年02月16日
    浏览(41)
  • 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)-- 第二题 智能服药助手 (已完结)

    其它题目 RC-u2 智能服药助手 智能看护中很重要的环节是安排需要服药的老年人的服药计划。 已知机器人需要照顾的某位老年人需要服用 N 种药物,但某些药物不宜间隔过短服用 —— 比如降糖药一般遵医嘱日服 3 次,两次之间需要间隔至少 4 小时。当需要服用的药物比较多

    2024年02月16日
    浏览(35)
  • 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)-- 第五题 树与二分图 (已完结)

    其它题目 RC-u5 树与二分图 设 G=(V,E) 是一个无向图,如果顶点集合 V 可分割为两个互不相交的子集 (A,B),并且每条边 (i,j)∈E 的两个端点 i 和 j 分别属于这两个不同的顶点子集,则称图 G 为一个二分图。 现在给定一棵树 T,要求选择树中两个没有边相连的结点 i 和 j,使得将无

    2024年02月16日
    浏览(36)
  • 2022 RoboCom 世界机器人开发者大赛-高职组 国赛(RC-v3 智能护理中心统计)

    题意: 给出各管理节点的关系,和每个管理节点的照护老人数量。 两种操作:1. 转院. 2. 查询 该管理节点以下总的老人人数. 知识点: 树。

    2024年02月15日
    浏览(46)
  • 2021 RoboCom 世界机器人开发者大赛-本科组(初赛)

    比赛介绍 比赛信息 比赛官网:https://www.robocom.com.cn/ 报名流程:https://www.robocom.com.cn/content.html?cid=386 工信部发文:https://www.robocom.com.cn/content.html?cid=367 中国教育学会清单:https://m.cahe.edu.cn/site/content/14825.html 编程赛道通知:https://www.robocom.com.cn/content.html?cid=369 赛制说明: CAIA数

    2024年02月16日
    浏览(42)
  • 2021 RoboCom 世界机器人开发者大赛-本科组(决赛)

    1.绿地围栏 思路 模拟题目,主要是记住最后要把原点加入到目标点当中,不然最后一个测试点过不了。 代码 2.队列插入 思路× 不太会,每理解大佬的思路,以后有机会补 代码× 3.账户安全预警 输入样例1 输出样例1 输入样例2 输出样例2 思路 嵌套map,用外层map的键表示邮箱,

    2024年02月16日
    浏览(41)
  • 2021 RoboCom 世界机器人开发者大赛-高职组(初赛)

    编程题得分:100  总分:100 目录 7-1 机器人打招呼 (5分) 输入格式: 输出格式: 输入样例: 输出样例: 7-2 人脸识别 (10分) 输入格式: 输出格式: 输入样例 1: 输出样例 1: 输入样例 2: 输出样例 2: 7-3 月份输出 (10分) 输入格式: 输出格式: 输入样例: 输出样例: 7-4 字

    2024年02月12日
    浏览(47)
  • 2021 RoboCom 世界机器人开发者大赛-本科组(复赛)

    官方题解 分数 20 7-1 冒险者分队 一个莫名其妙的思维 分数 25 7-2 拼题A打卡奖励 01背包的变形,在面临超时的情况下,明智的选择另一种作为限制 分数 25 7-3 快递装箱 大模拟,没拿到满分,就十六分,不想改了,累了 分数 30 7-4 塔防游戏 头一次写二位最短路

    2024年02月16日
    浏览(41)
  • 2021 RoboCom 世界机器人开发者大赛-本科组(决赛)题解

    市政规划了一块绿地,需要采购一批围栏将绿地围起来。 为了简单起见,我们假设绿地的形状是个封闭连通的规则多边形,即所有边都是互相垂直或平行的,并且没有交叉的十字边。我们指定某条垂直边上的一个点为原点 (0,0),然后按照顺时针记录这个多边形的拐角顶点的位

    2024年02月14日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包