题面(过于冗长,主要是对通信题的一些解释)

题解

1.通信题什么意思

并不是两个程序同时跑。

而是你写两个不能单独运行的子程序,然后由评测方调用,检查是否通过数据点。

通信题一般会给你很多函数,有些是你可以不用手写定义就使用的函数(一般在“有效文件名.h”里定义了,你得在代码里加上它的头文件,用""而不是<>),这是第一类,有些是你需要定义其内容的函数(这类函数将被评测方调用,用以检查是否通过),这是第二类。

所以,形象地说,你要写的算法部分得被拆分到各个第二类函数里,适应题目告诉你的调用顺序。你的两个程序是死的,它们没有主函数,只会在被评测方调用时“激活”特定的函数并运行。此时你可能就不得不把算法中的一些循环展开,多加些 if, else 把算法拆分到不同函数中 。

因此,大多通信题都可以算是模拟题了吧。

2.此题题解

它要求最短路,那我们就跑个Dijkstra好了。算法过程应该都清楚:

  1. 找到目前没计算过的距离起点最近的转移点。
  2. 更新邻接点的最短路。
  3. 重复此过程直到所有点都计算过。

此时的局限是,A 和 B 任一方都不知道所有的边,只知道一部分。其实这个很好办,对于第二步,我们就利用自己知道的边转移就行了,然后为了保证第一步得到的是正确的转移点和最短路,需要 A 和 B 进行一次交流。

先向对方发送自己计算的转移点最短路长度,然后当一方知道了对方的最短路长度,就可以比较得出谁的转移点是正确的。

比较得出自己的转移点更优的话,需要向对方发送自己的转移点编号,因为对方此时只知道你的更优,以及转移点最短路长度是多少,但是不知道转移点具体的编号。

比较得出对方转移点更优的话,则等待对方发送的编号。

传输的数据长度是

n

(

log

n

+

2

log

(

w

n

)

)

n(\log n+2*\log (w*n))

n(logn+2∗log(w∗n)) 的,长度会超过 58000。我们加一个小优化:每次发送最短路长度 - 上一个转移点的最短路。由 Dijkstra 算法的性质可以证明这个数是不超过 w 的数据范围的,那么数据长度就优化到了

n

(

log

n

+

2

log

w

)

n(\log n+2*\log w)

n(logn+2∗logw) ,刚好卡到 58000 .

CODE

实现

由于 A 和 B 的代码类似,就拿 A 说吧。

我们会在 InitA() 函数中知道 n,m 和边的信息,因此在这个函数中初始化算法,我们把要用到的信息存到全局变量中:

InitA(...) {
记录 n,m;
存边, 建图;
更新 0 号点的邻点最短路;
last_ans = 0;
开始 dijkstra:
交流: 发送转移点最短路...
}

然后呢?我们发现接收函数是外面的 ReceiveA() ,此时就不得不结束 InitA() 了啊,因此我们得多用一些变量记录算法流程,当前接收信息的目的,接收的完整度等。在 ReceiveA() 中我们得判断当前接收的信息是否完整(因为每次只有一个 bool ,得接收多次),若已100%接收,则把下一次接收信息之前的操作都做完,退出函数(等待下一次被调用)。

还是比较考验模拟能力的。

为了防止变量重名编译错误,需要把全局变量等放进空 namespace 里。

A.hB.h 中是对各个函数的声明。

A.cpp

#include "A.h"
#include <bits/stdc++.h>
using namespace std;
namespace {
#define MAXN 2005
#define DB double
#define LL long long
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
int n,m,s,o,k;
struct it{
int v,w;it(){v=w=0;}
it(int V,int W){v=V;w=W;}
};
vector<it> g[MAXN];
int dp[MAXN];
int tre[MAXN<<2],M;
int bing(int a,int b) {return dp[a] < dp[b] ? a:b;}
void maketree(int n) {M=1;while(M<n+2)M<<=1;}
void addtree(int x,int y) {
int s = M+x;tre[s] = y; s >>= 1;
while(s) tre[s] = bing(tre[s<<1],tre[s<<1|1]),s >>= 1;
}
int findall() {return tre[1];}
int CNT = 0,ctnm = 0,recnm = 0;
int flag = 0;
void sendnmA(int x,int bt) {
for(int i = bt-1;i >= 0;i --) {
bool tmp = (x & (1<<i));
SendA(tmp);
}return ;
}
int t,las = 0;
void calcu() {
for(int i = 0;i < (int)g[t].size();i ++) {
int y = g[t][i].v,w = g[t][i].w;
if(dp[t] + w < dp[y]) {
dp[y] = dp[t] + w;
addtree(y,y);
}
}
addtree(t,0);
CNT ++;
flag = 1;
t = findall();
if(CNT >= n || !t) {flag = -1;return ;}
sendnmA(min(511,dp[t]-las),9);
return ;
}
}
void ReceiveA(bool x) {
recnm <<= 1;recnm += x;
ctnm ++;
if(flag == 1 && ctnm >= 9) {
if(recnm+las >= dp[t]) {
sendnmA(t,11);
las = dp[t];
ctnm = recnm = 0;
calcu();
}
else {
flag = 0;
las = recnm + las;
ctnm = recnm = 0;
}
return ;
}
if(flag == 0 && ctnm >= 11) {
t = recnm;dp[t] = las;
ctnm = recnm = 0;
calcu();
return ;
}
return ;
}
void InitA(int N, int M, vector < int > U, vector < int > V, vector < int > W) {
n = N;m = M;
for(int i = 1;i <= m;i ++) {
s = U[i-1]+1; o = V[i-1]+1; k = W[i-1];
g[s].push_back(it(o,k));
g[o].push_back(it(s,k));
}
maketree(n);
for(int i = 0;i <= n;i ++) dp[i] = 0x7f7f7f7f;
dp[1] = 0;t = 1;las = 0;
calcu();
return ;
}
vector < int > Answer() {
vector < int > ans;
for(int i = 1;i <= n;i ++) {
ans.push_back(dp[i]);
}
return ans;
}

B.cpp

#include "B.h"
#include <bits/stdc++.h>
using namespace std;
namespace {
#define MAXN 2005
#define DB double
#define LL long long
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
int n,m,s,o,k;
struct it{
int v,w;it(){v=w=0;}
it(int V,int W){v=V;w=W;}
};
vector<it> g[MAXN];
int dp[MAXN];
int tre[MAXN<<2],M;
int bing(int a,int b) {return dp[a] < dp[b] ? a:b;}
void maketree(int n) {M=1;while(M<n+2)M<<=1;}
void addtree(int x,int y) {
int s = M+x;tre[s] = y; s >>= 1;
while(s) tre[s] = bing(tre[s<<1],tre[s<<1|1]),s >>= 1;
}
int findall() {return tre[1];}
int CNT = 0,ctnm = 0,recnm = 0;
int flag = 0;
void sendnmB(int x,int bt) {
for(int i = bt-1;i >= 0;i --) {
bool tmp = (x & (1<<i));
SendB(tmp);
}return ;
}
int t,las = 0;
void calcu() {
for(int i = 0;i < (int)g[t].size();i ++) {
int y = g[t][i].v,w = g[t][i].w;
if(dp[t] + w < dp[y]) {
dp[y] = dp[t] + w;
addtree(y,y);
}
}
addtree(t,0);
CNT ++;
flag = 1;
t = findall();
if(CNT >= n || !t) {flag = -1;return ;}
sendnmB(min(511,dp[t]-las),9);
return ;
}
}
void ReceiveB(bool x) {
recnm <<= 1;recnm += x;
ctnm ++;
if(flag == 1 && ctnm >= 9) {
if(recnm+las > dp[t]) {
sendnmB(t,11);
las = dp[t];
ctnm = recnm = 0;
calcu();
}
else {
flag = 0;
las = recnm + las;
ctnm = recnm = 0;
}
return ;
}
if(flag == 0 && ctnm >= 11) {
t = recnm;dp[t] = las;
ctnm = recnm = 0;
calcu();
return ;
}
return ;
}
void InitB(int N, int M, vector < int > U, vector < int > V, vector < int > W) {
n = N;m = M;
for(int i = 1;i <= m;i ++) {
s = U[i-1]+1; o = V[i-1]+1; k = W[i-1];
g[s].push_back(it(o,k));
g[o].push_back(it(s,k));
}
maketree(n);
for(int i = 0;i <= n;i ++) dp[i] = 0x7f7f7f7f;
dp[1] = 0;t = 1;las = 0;
calcu();
return ;
}

蕞短鹭(artskjid) (⭐通信题/模拟⭐)的更多相关文章

  1. ACM: NBUT 1105 多连块拼图 - 水题 - 模拟

    NBUT 1105  多连块拼图 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:  Practice  Appoint ...

  2. Sdut 2409 The Best Seat in ACM Contest(山东省第三届ACM省赛 H 题)(模拟)

    题目描述 Cainiao is a university student who loves ACM contest very much. It is a festival for him once ...

  3. hdu 4706 Children's Day 2013年ICPC热身赛A题 模拟

    题意:按字母顺序排列成n型,简单的模拟题. 当字母排到z时从a开始重新排起. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * Blog: ...

  4. 2019.3.16 noiac的原题模拟赛

    RT,这太谔谔了,我不承认这是模拟赛 但是虽然是搬了三道题,题目本身也还能看,就这么着吧 (怎么机房里就我一道原题都没做过啊 T1 CF24D Broken Robot 比较简单地列出式子之后,我们发 ...

  5. CodeForces 686A Free Ice Cream (水题模拟)

    题意:给定初始数量的冰激凌,然后n个操作,如果是“+”,那么数量就会增加,如果是“-”,如果现有的数量大于等于要减的数量,那么就减掉,如果小于, 那么孩子就会离家.问你最后剩下多少冰激凌,和出走的孩子 ...

  6. CodeForces 342B Xenia and Spies (水题模拟,贪心)

    题意:给定 n 个间谍,m个区间,一个 s,一个f,然后从 s开始传纸条,然后传到 f,然后在每个 t 时间在区间内的不能传,问你最少的时间传过去. 析:这个题,就模拟一下就好,贪心策略,能传就传,找 ...

  7. NOIp2017真题模拟赛 By cellur925

    果然我还是最菜的==不接受反驳 (先考了day2喵喵喵) Day2 T1:奶酪 期望得分:100分 实际得分:100分 考察:并查集 思路:这题其实之前做过了==.思路还是比较清晰的,读入时预处理出可 ...

  8. NOIp 2015真题模拟赛 By cellur925

    果然我还是最菜的==不接受反驳== Day1 T1:神奇的幻方 思路:直接模拟即可,由于当前放法只与上一放法有关系,用两个变量记录一下即可.10分钟内切掉== 预计得分:100分 实际得分:100分 ...

  9. NEFU 2016省赛演练一 I题 (模拟题)

    这题没名字 Problem:I Time Limit:2000ms Memory Limit:65535K Description Now give you an interger m and a s ...

随机推荐

  1. 我所使用的生产 Java 17 启动参数

    JVM 参数升级提示工具:jacoline.dev/inspect JVM 参数词典:chriswhocodes.com Revolut(英国支付巨头)升级 Java 17 实战:https://ww ...

  2. Django——表单

    一.前言 看了下教程,以为表单很简单呢,结果搞了一两个钟才弄懂,哈哈哈,所以说不要小瞧每一件事. 先说明下HTTP请求: HTTP协议以"请求-回复"的方式工作.客户发送请求时,可 ...

  3. 在.NET 6.0上使用Kestrel配置和自定义HTTPS

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本章是<定制ASP NET 6.0框架系列文章>的第四篇.在本章,我们 ...

  4. 【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()

    问题描述 算法 Algorithms (第四版)书中,第1章:基础编程模型第15题: 结果: 编写一个静态方法 histogram(), 接受一个整型数组a[] 和一个整数M为参数,并返回一个大小为M ...

  5. 广义径向基网络(RBF网络)

  6. 意想不到的Python ttkbootstrap 制作账户注册信息界面

    嗨害大家好,我是小熊猫 今天给大家来整一个旧活~ 前言 ttkbootstrap 是一个基于 tkinter 的界面美化库,使用这个工具可以开发出类似前端 bootstrap 风格的tkinter 桌 ...

  7. HMS Core安全检测服务如何帮助大学新生防范电信诈骗?

    一年一度的高考结束了,很多学生即将离开父母,一个人踏入大学生活,但由于人生阅历较少,容易被不法分子盯上. 每年开学季也是大一新生遭受诈骗的高峰期,以下是一些常见的案例.有的骗子会让新生下载注册一些恶意 ...

  8. mybatis-拦截器实际应用-替换表名-2022新项目

    一.业务场景 考虑到新项目中部分与业务数据相关的表在后期数据量会比较大,架构师在最开始设计项目中与业务数据相关的表时,就已经考虑使用分表来 进行处理,给业务数据相关的每张表都添加统一批次的后缀,查询这 ...

  9. 1_day01_操作系统安装

    操作系统安装 内容介绍 1.制作U盘启动器 2.备份驱动 3.安装操作系统 4.驱动更新 5.依赖库检测 6.系统漏洞修复 7.系统布局优化 一.制作U盘启动器 1.1 下载老毛桃 下载老毛桃pe工具 ...

  10. Eslint 项目笔记

    1.代码下一行不要验证报错 代码的上一行打上注释 <--eslint-disable-next-line-->