2020年首届算法竞赛网络挑战赛直播讲解课程
比赛链接
菜鸡的我,第四名。。
A 矛盾激化
题意
给定地图,这个地图有两个出口,现在我们需要求出从所有点到任意一个出口的距离中的最短路径的最大值
本题为输出答案题,给定你一种情况,然后输出它的答案
题解
如果实在不会,可以手查(滑稽)
如果直接从每个点开始搜一遍最短距离不现实
因为只有两个出口,所以我们可以从出口出发然后跑两边BFS,每个点都维护一个距离的最小值
有几个坑点:
1.从出口往里面跳的时候只能跳一个格子
2.从别的格子跳往其他格子时只能跳两个格子
3.跳两格的时候还要判断中间隔过去的一格是不是空格
4.输入的格子有些恶心人
代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>const int INF = 2147483647;using namespace std;int n, m, sx[3], sy[3], cnt, ans;
char map[208][90];
int dis[208][90];
int dx[5] = {0, 2, 0, -2};
int dy[5] = {2, 0, -2, 0};int rx[5] = {0, 1, 0, -1};
int ry[5] = {1, 0, -1, 0};
struct node {int x, y, sum;
}temp, now;
queue<node> Q;
bool vis[208][90];inline void BFS(int num) {memset(vis, 0, sizeof(vis));while (!Q.empty()) Q.pop();vis[sx[num]][sy[num]] = 1;temp.sum = 0, temp.x = sx[num], temp.y = sy[num];Q.push(temp);while (!Q.empty()) {now = Q.front();int x = now.x, y = now.y, s = now.sum;Q.pop();dis[x][y] = min(s, dis[x][y]);for(int i=0; i<4; i++) {int xx = dx[i]+x, yy = dy[i]+y;//走两格 int zx = rx[i]+x, zy = ry[i]+y;//走一格 if(!vis[xx][yy] && map[xx][yy] == ' ' && xx <= 2*n+1 && xx > 0 && yy <= 2*m+1 && yy > 0 && map[zx][zy] == ' ' && (x != sx[num] || y != sy[num])) {//普通跳两格 vis[xx][yy] = 1;temp.x = xx, temp.y = yy, temp.sum = s+1;Q.push(temp);}if(!vis[zx][zy] && map[zx][zy] == ' ' && x == sx[num] && y == sy[num] && zx <= 2*n+1 && zy <= 2*m+1 && zx > 0 && zy > 0) {//当从出口往里跳 vis[zx][zy] = 1;temp.x = zx, temp.y = zy, temp.sum = s+1;Q.push(temp);}}}
}int main() {scanf("%d%d", &m, &n);for(int i=1; i<=2*n+1; i++) {for(int j=1; j<=2*m+1; j++) {dis[i][j] = INF;}}gets(map[0]);for(int i=1; i<=2*n+1; i++) {gets(map[i]+1);for(int j=1; j<=2*m+1; j++) {if(i == 1 || j == 1 || i == 2*n+1 || j == 2*m+1)//边界 if(map[i][j] == ' ') {//记录出口 sx[++cnt] = i;sy[cnt] = j;}}}BFS(1);BFS(2);//从两个出口开始bfs for(int i=1; i<=2*n+1; i++) {for(int j=1; j<=2*m+1; j++) {if(dis[i][j] != INF)ans = max(ans, dis[i][j]);}}printf("%d", ans);
}
B 我去前面探探路
题意
对于一个树,我们可以进行两种操作,第一种:选择一个节点,与该节点相连的边会被标记。第二种:选择第一个节点,与该节点相连的边会被标记,同时与该节点相连的节点的相连的边也会被标记。这两种操作有各自的花费。问将所有边标记所需花费是多少
题解
树形dp
我们可以发现,在儿子节点操作2,与自己操作1对父亲节点的影响一样的
也就是这两种情况在后效性上是等价的
也就是他自己其实也可以被对兄弟操作2给影响
我们可以得到:
dp[u][0] :以点u为根的子树下的边全部被覆盖,且没有向u节点上方覆盖。也就是u不放,u的子节点只能进行操作1
dp[u][1]:以点u为根的子树下的边全部覆盖,且向上覆盖长度为1。u进行操作1,或者u为空,u的子节点进行操作2
dp[u][2]:以点u为根的子树下的边全部覆盖,且向上覆盖长度为2。u进行操作2
dp[u][3]:以点u为根的子树的子树里的边都被覆盖,但是u和子树间的边不一定被覆盖。也就是父亲节点进行操作2
v是u的儿子节点
dp[u][3]是为了处理 1-2-3-4-5-6-7-8-9,c1=10,c2=15这种极端的情况,只要c2覆盖3和7,就能覆盖所有的边
dp[u][j]是不同情况 覆盖以u为节点的子树的最小代价
int t=min(dp[v][0],min(dp[v][1],dp[v][2]));dp[u][0]+=dp[v][1]; //u的子节点v是1,u才能是0(向上覆盖长度0),不能有2,否则就会向上覆盖dp[u][1]+=t; //向上覆盖长度是1,有两种选择: 1.在u上放置c1,v上1,2,3随意 2.u上不放,在一个v上放置c2,然后其他的v上随意,dp[u][2]+=min(t,dp[v][3]); //u放置了c2,子节点v处于什么状态(0,1,2,3)都行dp[u][3]+=t; //因为是状态3,所以u和v之间的边被它的父节点覆盖,所以v不受上面影响,可以当作一个单独的树看待optimal=min(optimal,dp[v][2]-t); //其中一个v上放置c2,选择增加费用最小的一个v
代码
#include<iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=10005,maxc=1005,INF=0x3f3f3f3f;
int n,c1,c2,a,b,dp[maxn][4];
//dp[u][v],v=2,1,0,把放置的装置看作势,也就是v的值,然后势向周围逐层减小
// 当u上放置c2,v=2,u上放置c1或者离c2一跳是v=1,当u离c1一跳或者c2两跳时,v=0
//当v=0时,u的子节点不能全为0,u可以放置东西,如果一个点上内有多个v值,取最高的
//
//dp[u][0]为在u不部署,而且父节点不为0的情况
// dp[u][1]为在u部署C1,dp[u][2]为在u部署C2
// dp[u][3]为在u不部署,而且父节点为0的情况,也就是说,子节点有一个必须为2
// 覆盖以u为节点的子树的最小代价//dp[u][0]为覆盖子树,且向上覆盖长度为0,就是u不放,u的子节点只能放c1
// dp[u][1]为覆盖子树,且向上覆盖长度为1,就是在u放置c1,或者在u的子节点放c2
// dp[u][2]为覆盖子树,且向上覆盖长度为2,也就是在u放置c2
// dp[u][3]为u的儿子节点为根的子树被全部覆盖,但是u和它的儿子之间的边可能没被完全覆盖(就是说父节点上有c2,所以不需要)
// [3]是为了处理 1-2-3-4-5-6-7-8-9,c1=10,c2=15这种极端的,只要c2覆盖3和7,就能覆盖所有的边
// 覆盖以u为节点的子树的最小代价
vector<int> graph[maxn];void dfs(int u,int fa){dp[u][0]=0;dp[u][1]=c1;dp[u][2]=c2;dp[u][3]=0;if(graph[u].empty()) return;int optimal=INF,total=0;for(auto iter=graph[u].begin();iter!=graph[u].end();++iter){ //遍历子节点int v=*iter;if(v==fa) continue;dfs(v,u);int t=min(dp[v][0],min(dp[v][1],dp[v][2]));dp[u][0]+=dp[v][1]; //u的子节点v是1,u才能是0(向上覆盖长度0),不能有2,否则就会向上覆盖dp[u][1]+=t; //向上覆盖长度是1,有两种选择: 1.在u上放置c1,v上1,2,3随意 2.u上不放,在一个v上放置c2,然后其他的v上随意,dp[u][2]+=min(t,dp[v][3]); //u放置了c2,子节点v处于什么状态(0,1,2,3)都行dp[u][3]+=t; //因为是状态3,所以u和v之间的边被它的父节点覆盖,所以v不受上面影响,可以当作一个单独的树看待optimal=min(optimal,dp[v][2]-t); //其中一个v上放置c2,选择增加费用最小的一个v}total=optimal+dp[u][3];dp[u][1]=min(dp[u][1],total);
}int main(void){while(cin>>n>>c1>>c2 && n){// memset(dp,INF,sizeof(dp));for(int i=1;i<=n;++i) graph[i].clear();for(int i=1;i<n;++i){scanf("%d%d",&a,&b);graph[a].push_back(b);graph[b].push_back(a);}dfs(1,-1);printf("%d\n",min(dp[1][0],min(dp[1][0],dp[1][1])));}
}
C 数列
题意
题解
题目中说最后的时候a=0,b=0,c=0作为结束标志
最后一行的元素一定是上一行的答案
那我们就可以逆着往前推导
根据公式
lastans就是上一行的答案,把下一行的三个式子带入第一行,就可以求出公式,可以解出再上个提问的答案。。。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=50004;
const int man=5e5+3;
ll w[maxn];
struct node{ll a,b,c;
}x[man];
ll a1;
ll sum[man];
int main()
{// freopen("in.txt","r",stdin);int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lld",&w[i]);}int tot=1;while(~scanf("%lld%lld%lld",&x[tot].a,&x[tot].b,&x[tot].c)){tot++;
// if(x[tot-1].a==-3&&x[tot-1].b==-3&&x[tot-1].c==-3)break; }tot--;sum[tot]=-x[tot].a;for(int i = tot-1; i;i--) {a1 = (0ll + w[sum[i+1]] * sum[i+1] + w[sum[i+1]] *w[sum[i+1]] * (sum[i+1] + 1) + 1);if(a1 == 0) sum[i] = 1;else sum[i] = -(0ll + x[i].a * (sum[i+1] + 1) * w[sum[i+1]] * w[sum[i+1]] + w[sum[i+1]] * sum[i+1] * (x[i].b + 1) + x[i].c + sum[i+1]) / a1;}for(int i=2;i<=tot;i++){printf("%lld\n",sum[i]);}return 0;}
D 点名
题目
在体育课上,同学们常常会迟到几分钟,但体育老师的点名却一直很准时。
老师只关心同学的身高,他会依次询问当前最矮的身高,次矮的身高,第三矮的身
高,等等。在询问的过程中,会不时地有人插进队伍里。你需要回答老师每次的询问
题解
使用大根堆和小根堆来解决第k小的问题
建立一个大根堆qu2(大元素在上面),建立一个小根堆qu1
然后大根堆qu2来维护第k小
每次有学生入队(新增元素进入我们的两个堆)
我们先让学生进入大根堆qu2,之后让qu2中最大的元素进入小
根堆qu1,这一步目的是为了时刻保持我们大根堆qu2中最大值是我们的第k大,也时刻保持qu2中元素只有k个。
如果我们想求第k+1大,只需将qu1中的最小值调入我们qu2中
。我们qu2中的最大值就是我们的第k+1大。
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
typedef long long ll;
using namespace std;
const int maxn=3e4+9;
long long a[maxn];
long long b[maxn];
priority_queue <ll,vector<ll>,greater<ll> >q1;
priority_queue <ll,vector<ll>,less<ll> >q2;
int main()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%lld",&a[i]);}for(int i=1;i<=m;i++){scanf("%lld",&b[i]);}for(int i=1;i<=m;i++){for(int j=b[i-1]+1;j<=b[i];j++){q2.push(a[j]);q1.push(q2.top());q2.pop();}q2.push(q1.top());q1.pop();printf("%lld\n",q2.top());}return 0;
}
E 蚂蚁
F 耐久度
G 内存管理
H 采集香料
I 青蛙过河
J 膜法区间
2020年首届算法竞赛网络挑战赛直播讲解课程相关推荐
- 2020年第十八届西电程序设计竞赛网络预选赛之Problem C 没人比我更懂 COVID-19
题目描述 现在,一种高度危险的病毒袭击了学园都市,人们陷入危难之中. 作为蓝星上最无所不知的人,你对病毒基因了如指掌.为了拯救即将废弃的 校赛,行星防御理事会找到了你. 现在你必须找出病毒所有可能的变 ...
- 2020年第十八届西电程序设计竞赛网络预选赛之Problem B 祖玛 1
题目描述 祖玛是一款著名的益智类游戏,玩家控制发射器发射小球,有三个或三个以 上颜色相同的小球相连即可消去,消去之后两边的小球会自动接在一起,若产 生了连续大于等于三个颜色相同的小球,还会继续消去. ...
- 2020中国大学生程序设计竞赛(CCPC) - 网络选拔赛 1005 Lunch (杭电 6892)
2020中国大学生程序设计竞赛(CCPC) - 网络选拔赛 1005 Lunch (杭电 6892)(类尼姆博弈) #include<cstdio> #include<iostrea ...
- 技术干货| 详解AI国际顶会NeurIPS 2020的黑盒优化竞赛冠军算法——HEBO算法
异方差演化贝叶斯优化(Heteroscedastic evolutionary bayesian optimisation, HEBO)算法是华为诺亚实验室提出的优化算法框架.该算法击败NVIDIA, ...
- 2020年“磐云杯”网络空间安全技能竞赛全国拉赛
2020年"磐云杯"网络空间安全技能竞赛全国拉赛 一.竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 单兵模式系统渗透测试 任务1 Wireshark数据包分析 ...
- 2020年“磐云杯”网络空间安全技能竞赛武汉拉练赛赛题及解析(超详细)
2020年"磐云杯"网络空间安全技能竞赛全国拉赛 "磐云杯"竞赛阶段 "磐云杯"任务拓扑图 "磐云杯"武汉拉练赛竞赛任务 ...
- 2020 年 “游族杯” 全国高校程序设计网络挑战赛
2020 年 "游族杯" 全国高校程序设计网络挑战赛(2020.5.23) 这场只出了两题,很蠢. 我真的严重怀疑出题人的英语水平,平均一题得读将近一小时题目- A.Amateur ...
- 【数据竞赛】2020 Kaggle 10大竞赛方案汇总
作者: 尘沙黑夜 2020 Kaggle 10大竞赛方案汇总 1 2020kaggle精选10大赛事汇总 1.1 2019 Data Science Bowl(3493只队伍) 1.2 Tens ...
- 挑战程序设计竞赛_我系首次参加第六届中国大学生程序设计竞赛网络预选赛
点击上方蓝字关注 「龙外信息工程系」 讲述有温度的故事 传递有态度的思想 2020年9月20日12时至17时,第六届中国大学生程序设计竞赛网络赛预选赛在杭州电子科技大学OJ成功举办,黑龙江外国 ...
最新文章
- JavaScript语言基础13
- 如何列出JavaScript对象的属性?
- 济南python工资一般多少钱-济南python编程课程培训哪家好
- ubuntu160.4+anaconda3 +tensorflow1.140 +keras2.2.5安装
- 信息隐藏将txt文件合并到jpg文件中_使用Kali Linux在图像内隐藏机密消息—可在任何Linux发行版使用
- 基于Django的博客系统
- mac上远程连接windows
- Pytorch基础(一) 初始tensor
- Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization
- 实用的技巧之免费下载百度文库VIP文章
- VMware Workstation 12 pro + 激活码+VMware Workstation 10 + 激活码
- 干货:前端性能优化之图片篇
- 西门子软件测试教程 博客,西门子视频教程合集
- matlab 仿真光学实验报告,基于matlab的光学实验仿真毕业论文.doc
- 技嘉x58不支持服务器内存,一般机箱放不下 技嘉X58送海盗船内存
- 服务器ssd硬盘格式化,格式化没你想象的简单 格式选错了对SSD有损
- android电脑手柄游戏平台,玩转PC、安卓TV、Stam平台等多平台的游戏手柄——北通斯巴达2...
- iOS12.3正式版不能更新是怎么回事(解决办法)
- MySQL源代码的海洋中游弋 初探MySQL之SQL执行过程
- Python爬取马蜂窝城市游记
热门文章
- rabbitmq入门_Rabbit MQ 入门
- oracle 有计划任务吗,oracle计划任务的问题
- java 接口的静态方法_Java8新特性:接口的默认方法与接口的静态方法
- 二分法查找是基于有序_201,查找顺序查找
- c语言电报关系的题目,c语言所有题目以跟答案.doc
- 软件层面可以做到重启本地串口吗_手机关机还是重启好?get这几招,手机更流畅...
- android loading封装_我们经常用的Loading动画居然还有这种姿势
- zynq网络时钟控制寄存器_ZYNQ笔记(6):普通自定义IP封装实现PL精准定时中断...
- leetcode209. 长度最小的子数组(滑动窗口)
- 7-1 内存分区分配--首次适应算法 (100 分)