2021RoboCom世界机器人开发者大赛-本科组(初赛)

1、懂的都懂

由于本题数据范围很小,所以直接四层for循环枚举预处理所有可能的四个数的和,然后对于新图中每个数的四倍,判断是否出现过即可

C++代码:

#include<iostream>
using namespace std;
const int N=55;
int a[N];
bool st[1040];//260*4
int main(){int n,k;cin>>n>>k;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)for(int k=j+1;k<=n;k++)for(int l=k+1;l<=n;l++){int t=a[i]+a[j]+a[k]+a[l];st[t]=true;//标记出现过}while(k--){int m,flag=0;cin>>m;while(m--){int x;cin>>x;if(!st[x*4])flag=1;//判断x的四倍是否出现过,如果没出现过,则与原图不相似}if(flag)puts("No");else puts("Yes");}return 0;
}

2、芬兰木棋

- 题目分析:

要求:

  • 如果仅击倒 1 根木棋,则得木棋上的分数。
  • 如果击倒 2 根或以上的木棋,则只得击倒根数的分数。
  • 满足以上两个条件,求获得分数最大,最少需要扔多少次大木棋

所以对于每个方向,从前往后遍历每个木棋:

1、如果木棋的分数大于1,则该木棋一定要单独扔一次大木棋,否则分数一定不是最多

2、如果出现一连串的小木棋的分数等于1,则对这一连串的小木棋扔一次大木棋即可

3、如果只有一个单独的1,则也需要单独扔一次大木棋

由此可知:最大分数一定是所有分数之和

一开始以为只要斜率相同就可以一起处理了,然后遇到全是1的就分成一次投。后来写了发现答案不对劲,斜率相同的点可能贯穿两个象限。如一、三象限,但这两个象限投木棋的方向是不一样的,一个是右上,一个是左下。所以我们需要单独处理四个象限,记得不要忘了坐标轴上的点,也有四种情况↑、↓、←、→一共是八种情况,所以在存储每个斜率的时候还要存储它们的位置(即象限)信息

处理完以上信息之后,对于每种情况,即斜率和象限都相同的的情况

我们需要从前往后枚举每个点,但是何为从前往后呢?

根据题意,是按照到原点的距离进行排序,然后枚举每个点。由于还需判断该点的分数是否等于1,故每种情况的每个点我们要存储两个信息(该点到原点的距离、该点的分数)

typedef pair<double,int> PDI; 

存储结构可以用map<PDI,vector<PDI>> mp;//pair存储斜率和象限,vector存储该种情况的每个点的信息,即距离和分数

C++代码如下:

#include<iostream>
#include<map>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
typedef pair<double,int> PDI;
typedef long long LL;
int n,x,y,p,t;
int cnt,score;//cnt存储最少扔的次数,score存储最多可获得的分数 
double k;//斜率 
map<PDI,vector<PDI>> mp;//PII中存储斜率和象限,vector中存储到原点的距离和分数
int get(int x,int y){//得到象限位置信息//没有按照实际的象限编号,因为只要保证八种情况的编号不同即可if(x<0&&y<0)return 1;else if(x<0&&y==0)return 2;else if(x<0&&y>0)return 3;else if(x==0&&y<0)return 4;else if(x==0&&y>0)return 5;else if(x>0&&y<0)return 6;else if(x>0&&y==0)return 7;else if(x>0&&y>0)return 8;
}
int main(){cin>>n;for(int i=1;i<=n;i++){PDI u,v;//u存储斜率和象限信息,v存储距离和分数信息cin>>x>>y>>p;score+=p;//分数+pif(x!=0)k=1.0*y/x;//求斜率else k=0;//x等于0默认k为0,方便存储int t=get(x,y);//求位置u.first=k,u.second=t;//斜率和位置v.first=sqrt((LL)x*x+(LL)y*y),v.second=p;//距离和分数mp[u].push_back(v);}for(auto t:mp){vector<PDI> k=t.second;//pair默认按照第一个参数进行排序,故会按照距离进行排序sort(k.begin(),k.end());for(int i=0;i<k.size();i++){if(k[i].second>1)cnt++;else if(k[i].second==1){while(k[i].second==1&&i<k.size())i++;cnt++;//一连串的1扔一次i--;}}}cout<<score<<" "<<cnt<<endl;return 0;
}

3、打怪升级

题意分析:

  • 首先要找到空降位置

1、对每个点做一遍最短路,以怪物的能量作为路径长度,故每个点所能到达的最远的地方即为最难攻克的堡垒

2、对于每个点所能到的最远的地方对应的路径,找出这些路径的最小值,该最小值所对应的起点就是空降位置

  • 其次就是处理每个询问

1、用空降位置作为起点再跑一遍最短路

2、依次输出每次询问的最短路径和最大价值

C++代码如下:

#include<iostream>
#include<cstring>
using namespace std;
const int N=1010,INF=0x3f3f3f3f;
int g[N][N],w[N][N];
int dist[N],val[N];//dist存储最短路径,val[i]存的是走到该点最大的价值
bool st[N];
int pre[N];//pre[i]存走到该点的路径
int n,m,k,start,maxv=INF;;
//start存储空降位置,maxv存储每个点攻克最难攻克的堡垒所需的能量的最小值
void dijkstra(int u){//dijkstra算法求最短路模板memset(dist,0x3f,sizeof dist);memset(st,false,sizeof st);dist[u]=0;for(int i=0;i<n;i++){int t=-1;for(int j=1;j<=n;j++)if(!st[j]&&(t==-1 ||dist[j]<dist[t]))t=j;st[t]=true;for(int j=1;j<=n;j++){if(dist[j]>dist[t]+g[t][j]){dist[j]=dist[t]+g[t][j];//更新距离 val[j]=val[t]+w[t][j];//更新价值 pre[j]=t;//j的上一个点是t }else if(dist[j]==dist[t]+g[t][j]){//如果路径能量相同,则选择缴获武器价值最高的方案if(val[j]<val[t]+w[t][j]){val[j]=val[t]+w[t][j];//更新价值 pre[j]=t;//j的上一个点是t }}}}
}
int main(){memset(g,0x3f,sizeof g);scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int a,b,c,d;scanf("%d%d%d%d",&a,&b,&c,&d);g[a][b]=g[b][a]=c;//记录花费w[a][b]=d,w[b][a]=d;//记录价值}for(int i=1;i<=n;i++){//每一个点跑一下最短路,找到最合算的空降位置startdijkstra(i);int temp=0;//计算攻下最难攻克的堡垒所需要的能量for(int i=1;i<=n;i++)temp=max(temp,dist[i]);if(temp<maxv)maxv=temp,start=i;//如果能量小于maxv,则更新maxv和start}printf("%d\n",start);memset(val,0,sizeof val);memset(pre,0,sizeof pre);dijkstra(start);//从出发点出发,走到每个节点//处理k个询问scanf("%d",&k);while(k--){int x;scanf("%d",&x);int u=x,path[N],cnt=0;//path存储路径while(u){path[cnt++]=u;u=pre[u];//u更新为路径中它的前一个节点}for(int i=cnt-1;i>=0;i--){if(i>0)printf("%d->",path[i]);else printf("%d",path[i]);}printf("\n%d %d\n",dist[x],val[x]);}return 0;
}

4、疫情防控

题意分析:每天给出一个防控地区,若干个当天的行程,判断有多少个行程不能成形

1、暴力做法,可以骗17分

对于每个防控地区,都标记一下,然后dfs搜索从起点到终点是否有不经过防控地区的路线,如果有,则可以出行,如果没有,则不能出行

#include<iostream>
#include<cstring>
using namespace std;
const int N=50010,M=400010;
int h[N],e[M],ne[M],idx;
int state[N];//标记机场是否已经成为防控地区
bool st[N]; 
int n,m,d,flag;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int sta,int ed){//开始机场和结束机场st[sta]=true;if(state[sta])return;for(int i=h[sta];i!=-1;i=ne[i]){int j=e[i];if(j==ed&&state[j]==false){flag=1;return;}if(!st[j]&&!state[j])dfs(j,ed);}st[sta]=false;
}
int main(){cin>>n>>m>>d;memset(h,-1,sizeof h);while(m--){int a,b;cin>>a>>b;add(a,b),add(b,a);}while(d--){int c,q,ans=0;cin>>c>>q;state[c]=true;//c为防控地区while(q--){memset(st,false,sizeof st);int x,y;flag=0;cin>>x>>y;dfs(x,y);if(!flag)ans++;}cout<<ans<<endl;}return 0;
}

2、正解:并查集

分析:对于每个询问,我们要找是否有一条不经过任何防控地区的路线。换句话说,就是将所有不是防控地区的机场看成若干个连通块,然后判断起点和终点是否连通,如果连通,则可以出行,否则不能

假设一开始所有的机场就是若干个连通块,每次询问的时候就把当天变成防控地区的机场踢出连通块,然后就会发现这样并不好操作

正难则反易,虽然删除连通块中的点很麻烦,但是反过来想,往连通块里加点是很简单的,这可以通过并查集来完成

所以,我们可以离线处理,即先存储所有的询问,然后逆序处理每一天的询问,每次将一个机场加入到连通块中

C++代码:

#include<iostream>
#include<vector>
using namespace std;
const int N=1e5+10;
typedef pair<int,int> PII;
vector<int> v[N];//存储所有边 
vector<PII> query[N];//query[i]存储第i天的所有询问,每个询问的起点和终点 
int p[N];//并查集数组 
int day[N],ans[N];//day[i]:第i天变成防控地区的机场编号,ans[i]:第i天不能出行的路线数 
int n,m,d;
int find(int x){//找祖宗节点 + 路径压缩 if(p[x]!=x)p[x]=find(p[x]);return p[x];
}
int main(){cin>>n>>m>>d;for(int i=1;i<=n;i++)p[i]=i;//初始化并查集for(int i=1;i<=m;i++){int a,b;cin>>a>>b;//建一条无向边v[a].push_back(b);v[b].push_back(a);}//存储询问 for(int i=1;i<=d;i++){int k; cin>>day[i]>>k;//第i天的防控机场存入到day[i]中 p[day[i]]=0;//0标记该机场为防控机场while(k--){int a,b;cin>>a>>b;query[i].push_back({a,b});//第i天的所有询问都存入query[i]中} } //把所有没有在任何一天变成防控地区的机场合并成若干个连通块 for(int i=1;i<=n;i++)if(p[i]){for(int j=0;j<v[i].size();j++)//遍历所有的相邻节点if(p[v[i][j]])p[find(v[i][j])]=find(i);}//逆序处理每一天 for(int i=d;i>=1;i--){//先处理当天的每个询问 for(int j=0;j<query[i].size();j++){int fa=find(query[i][j].first);int fb=find(query[i][j].second);if(fa!=fb||fa==0)ans[i]++;//如果两个节点不连通或者都是防控地区,则该天不能出行的询问加一 }//然后把该天变为防控地区的机场变成正常机场 int k=day[i];p[k]=k;for(int j=0;j<v[k].size();j++)if(p[v[k][j]])p[find(v[k][j])]=k;//合并所有相邻的正常机场 }for(int i=1;i<=d;i++)cout<<ans[i]<<endl;//输出每一天的答案 return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux防火墙使用(firewalld与iptables)

防火墙概述 防火墙是一种由硬件和软件组合而成&#xff0c;在内部网和外部网之间、专有网和公共网之间构造的保护屏障&#xff0c;用以保护用户资料和信息安全的一种技术 防火墙作用在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题&#xff0c;从而实现…

VUE3初学入门-02-VUE创建项目

创建VUE项目的另一个方法 三种方法通过vue-cli进行创建通过npm进行创建比较 部署到nginx修改配置生成部署文件 三种方法 上一篇是在VSCODE中建立工作区&#xff0c;然后创建&#xff0c;属于命令加鼠标方式。个人感觉&#xff0c;在VSCODE基本上都是这样的操作&#xff0c;不是…

Superset超火的企业级可视化BI分析工具

Superset&#xff0c;听起来就像是超级集合&#xff0c;确实&#xff0c;它几乎集合了所有你需要的数据功能。简单说&#xff0c;它就是一个现代化、功能强大的数据可视化工具。 它支持各种数据库&#xff0c;有着丰富的可视化选项&#xff0c;可以用来创建漂亮的数据仪表盘&a…

【PYG】GNN和全连接层(FC)分别在不同的类中,使用反向传播联合训练,实现端到端的训练过程

文章目录 基本步骤GNN和全连接层&#xff08;FC&#xff09;联合训练1. 定义GNN模型类2. 定义FC模型类3. 训练循环中的联合优化解释完整代码 GNN和全连接层&#xff08;FC&#xff09;分别使用不同的优化器和学习率分别进行参数更新解释 基本步骤 要从GNN&#xff08;图神经网…

【JavaScript脚本宇宙】从实用工具到日期处理:深度解析JavaScript库的应用与优势

提升JavaScript开发效率利器大揭秘&#xff1a;6款神奇库全面解析 前言 JavaScript已成为前端开发中不可或缺的一部分。随着项目变得越来越复杂&#xff0c;使用模块加载库可以帮助我们更好地管理和组织代码。本文将介绍几个常用的 JavaScript 模块加载库&#xff0c;包括 Re…

Sklearn 入门案例教程

Sklearn 的基本概念 1.什么是 Sklearn&#xff1f;&#xff1a;Sklearn 是一个 Python 库&#xff0c;用于机器学习和数据科学的开发。 2.Sklearn 的组件&#xff1a;Sklearn 的组件包括机器学习算法、数据预处理、模型评估等。 3.Sklearn 的应用&#xff1a;Sklearn 的应用包…

Python面试宝典第6题:有效的括号

题目 给定一个只包括 (、)、{、}、[、] 这些字符的字符串&#xff0c;判断该字符串是否有效。有效字符串需要满足以下的条件。 1、左括号必须用相同类型的右括号闭合。 2、左括号必须以正确的顺序闭合。 3、每个右括号都有一个对应的相同类型的左括号。 注意&#xff1a;空字符…

Java中的异常处理与断路器模式

Java中的异常处理与断路器模式 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在软件开发过程中&#xff0c;异常处理是确保程序稳定性和可靠性的关键部分。J…

2-Protocol Buffer 基础(c++)

本教程提供了使用协议缓冲区的基本介绍。通过逐步创建一个简单的示例应用程序&#xff0c;介绍以下内容&#xff1a; 1.在.proto文件中定义消息格式。 2.使用 protocol buffer 编译器。 3.使用c protocol buffer API来写入和读取消息。 一、问题描述 将要使用的示例是…

Xilinx FPGA:vivado串口输入输出控制fifo中的数据

一、实验要求 实现同步FIFO回环测试&#xff0c;通过串口产生数据&#xff0c;写入到FIFO内部&#xff0c;当检测到按键信号到来&#xff0c;将FIFO里面的数据依次读出。 二、信号流向图 三、状态转换图 四、程序设计 &#xff08;1&#xff09;按键消抖模块 timescale 1ns…

python-django-LlamaIndex 精简版

&#x1f680; 一键安装LlamaIndex&#xff0c; pip install llama-index &#x1f4c1; 准备你的数据文件&#xff0c;无论是txt还是pdf&#xff0c;放入data文件夹&#xff0c;一切就绪。 &#x1f527; 简单几步&#xff0c;在views.py中集成LlamaIndex&#xff0c;代码如…

读书笔记-《魔鬼经济学》

这是一本非常有意思的经济学启蒙书&#xff0c;作者探讨了许多问题&#xff0c;并通过数据找到答案。 我们先来看看作者眼中的“魔鬼经济学”是什么&#xff0c;再选一个贴近我们生活的例子进行阐述。 01 魔鬼经济学 中心思想&#xff1a;假如道德代表人类对世界运转方式的期…

uniapp实现一个键盘功能

前言 因为公司需要&#xff0c;所以我.... 演示 代码 键盘组件代码 <template><view class"keyboard_container"><view class"li" v-for"(item, index) in arr" :key"index" click"changArr(item)" :sty…

初学Spring之 AOP 面向切面编程

AOP&#xff08;Aspect Oriented Programming&#xff09;面向切面编程 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 是面向对象&#xff08;OOP&#xff09;的延续 AOP 在 Spring 中的作用&#xff1a; 1.提供声明式事务 2.允许用户自定义切面 导…

Objects365数据集介绍

Objects365数据集介绍 什么是Objects365数据集&#xff1f;数据集的规模与内容数据集的特点数据集下载 什么是Objects365数据集&#xff1f; Objects365是一个大规模、高质量的物体检测数据集。该数据集旨在推动物体检测技术的发展&#xff0c;特别是在真实世界场景下的应用。O…

Python 学习之机器学习库(九)

Python的机器学习库种类繁多&#xff0c;每个库都有其独特的特性和应用场景。以下是一些主要的Python机器学习库&#xff0c;按照其功能和特点进行清晰归纳和分点表示&#xff1a; 1. NumPy ● 功能&#xff1a;NumPy是Python中用于科学计算的基础库&#xff0c;提供了高性能的…

【python】python当当数据分析可视化聚类支持向量机预测(源码+数据集+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

基于java+springboot+vue实现的校园外卖服务系统(文末源码+Lw)292

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;外卖信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

数据库SQL Server窗口函数、聚合函数

文章目录 窗口函数窗口函数分类窗口函数示例聚合函数示例注意事项 流水表提取最新状态 窗口函数 SQL Server中的窗口函数&#xff08;也称为分析函数&#xff09;是一组非常强大的SQL功能&#xff0c;**它们允许你在结果集的行上执行计算&#xff0c;而不需要将结果集分组为多…

React-tive优质开源项目

对于初学者来说&#xff0c;接触和学习React相关的优质开源项目是一个非常好的方式来提升编程技能&#xff0c;特别是对于理解React的实际应用和最佳实践。这里推荐几个React开源项目&#xff0c;它们通常会附带详细的文档和示例代码&#xff0c;帮助新手快速上手&#xff1a; …