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

题解

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. python:selenium测试登录在chrome中闪退

    问题描述:使用selenium.webdriver时测试网页,进行自动登录测试总是在登录成功时闪退.使用指定驱动器位置的方式chrome也会闪退 1.正常使用chrome驱动打开一个网页,正常访问 f ...

  2. 认识一下什么是JSP

    摘要:JSP,全称是Java Server Pages,即Java服务器页面,是由Sun Microsystems公司主导创建的一种动态网页技术标准. 本文分享自华为云社区<Java服务器页面- ...

  3. Elasticsearch学习系列三(搜索案例实战)

    Query DSL Es提供了基于JSON的完整查询DSL(Domain Specific Language 特定域的语言)来定义查询.将查询DSL视为查询的AST(抽象语法树).它由两种子句组成: ...

  4. Jmter入门教程

    Jmter入门教程 本文已同步到公众号,欢迎关注: 1. 简介 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件.相比Loadrunner而言,JMeter小巧轻便且免 ...

  5. 使用c++爬取股市数据,获取最新行情

    最近自己动手写个小软件(界面原生态,还没来得及加样式哈).每天看看潜力股懒人做法,不介意推荐.资源有限,只能观察一下低价股,分析一下运动规律,什么时候拉升,惯性如何 主要功能:读取网络数据:保存本地数 ...

  6. Pisa-Proxy 之 SQL 解析实践

    SQL 语句解析是一个重要且复杂的技术,数据库流量相关的 SQL 审计.读写分离.分片等功能都依赖于 SQL 解析,而 Pisa-Proxy 作为 Database Mesh 理念的一个实践,对数据库 ...

  7. RPA应用场景-银行回单查询

    场景概述银行回单查询 所涉系统名称银行网银 人工操作(时间/次) 5 分钟 所涉人工数量 4 操作频率不定时 场景流程 1.收到外派业务员申请查询收入银行回单的邮件: 2.依据邮件中提供的客户信息进入 ...

  8. 【题解】Educational Codeforces Round 82

    比较菜只有 A ~ E A.Erasing Zeroes 题目描述: 原题面 题目分析: 使得所有的 \(1\) 连续也就是所有的 \(1\) 中间的 \(0\) 全部去掉,也就是可以理解为第一个 \ ...

  9. Mark IntelliJ IDEA 2018.2.3破解

    来源:https://blog.csdn.net/qq_38060935/article/details/90377761

  10. SpringMVC-01

    1. 概述 1.1 概念 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 优点 使用简单,开发便捷(相比于Servlet) 灵活性强 项目请求响应架构演进: 软件三层 软件三层 ...