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

题解

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. 阶段性总结 GDOI 2022 PJ

    阶段性总结 GDOI 2022 PJ 比赛经过 Day ? ~ Day -1 半停课集训,补了很多东西,但是之前漏得太多了,结果是还有很多题没改 打了若干场 AtCoder ,承认自己思维的不足,训练 ...

  2. 国外卡组织的 交换费-interchangefee(发卡行服务费) 和 银联对比

    本文地址:https://www.cnblogs.com/hchengmx/p/15170391.html 1. 交换费(interchangefee)介绍 2. MasterCard 万事达卡 &a ...

  3. Java创建数据库新建表及初始化表

    方法一 package com.crt.openapi; import java.sql.DriverManager;import java.sql.ResultSet;import java.io. ...

  4. 【由浅入深_打牢基础】HOST头攻击

    [由浅入深_打牢基础]HOST头攻击 前几天一直准备别的事情,然后用了2/3天时间去挖了补天某厂的SRC,还是太菜了,最后提交了一个低危(还没出结果,还有点敏感信息泄露,感觉略鸡肋也没交),不过偶然发 ...

  5. 十分钟快速实战Three.js

    前言 本文不会对Three.js几何体.材质.相机.模型.光源等概念详细讲解,会首先分成几个模块给大家快速演示一盒小案例.大家可以根据这几个模块快速了解Three.js的无限魅力.学习 我们会使用Th ...

  6. C#/VB.NET 将PDF转为Excel

    PDF文档可以避免可防⽌他⼈⽆意中触到键盘修改⽂件内容.但是在避免他人⽆意修改的同时也妨碍了正常的修改.如果你想处理或修改PDF文档中的数据,不妨试试用Excel来实现.Excel拥有强大的数据处理功 ...

  7. 用python做个计算器不是轻轻松松吗~

    计算器 Kivy是一个免费的开源Python库,可以快速轻松地开发高度交互的跨平台应用程序. 这里我将使用Python中的Kivy包来构建一个计算器GUI.(https://jq.qq.com/?_w ...

  8. c# 怎样能写个sql的解析器

    c# 怎样能写个sql的解析器 本示例主要是讲明sql解析的原理,真实的源代码下查看 sql解析器源代码 详细示例DEMO 请查看demo代码 前言 阅读本文需要有一定正则表达式基础 正则表达式基础教 ...

  9. Elasticsearch深度应用(上)

    索引文档写入和近实时搜索原理 基本概念 Segments in Lucene 众所周知,Elasticsearch存储的基本单元是shard,ES种一个index可能分为多个shard,事实上每个sh ...

  10. NC16884 [NOI2001]食物链

    题目链接 题目 题目描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B,B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...