Contest

A. 输油管道问题

某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有 \(n\) 口油井的油田。从每口油井都要有一条输油管道沿最短路经 (或南或北) 与主管道相连。如果给定 \(n\) 口油井的位置, 即它们的 \(x\) 坐标(东西向)和 \(y\) 坐标(南北向), 应如何确定主管道的最优位置, 即使各油井到主管道之间的输油管道长度总和最小的位置? 证明可在线性时间内确定主管道的最优位置。 \(1\le n\le 10000\)。

观察到 \(x\) 坐标与答案无关,题目转变为求 \(\sum |Y-y_i|\) 的最大值。

贪心。易证,中位数即为 \(Y\) 的值。

(当然我在考场上是用玄学二分做出来的。)

B. ssoj3147 跑步(run)

小 A 要参加一次 1000 米跑步比赛。 一开始他的速度为 1 m/s,在跑步过程中他会越跑越累,所以会进行若干次减速。第一次减速后,速度变为 \(\frac{1}{2}\) m/s;第二次减速后,速度变为 \(\frac{1}{3}\) m/s,依次类推。你现在知道小 A 会在什么时间或者是哪里进行减速,有 \(n\) 个这样的事件:T x 表示小 A 会在比赛开始后 \(x\) 秒进行一次减速。D x 表示小 A 会在恰好跑了 \(x\) 米之后进行一次减速。现在给你这些事件。你要帮小 A 算出他用这种方式到达终点所需要的时间是多少秒。可能存在两个事件恰好同时发生,那么在这一时刻速度就会减小两次。

模拟即可。注意时间、位移、速度的先后顺序,以及哨兵变量自增的时机。考场上就是这点折腾了我好久。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int n, t[10003], d[10003], vn=1;
double lt, ld, v=1; int main() {
scanf("%d", &n);
for (int k=1; k<=n; ++k) {
int a=0;
char c=getchar(); while (c!='T' && c!='D') c=getchar(); scanf("%d", &a);
if (c=='T') t[++t[0]]=a; else d[++d[0]]=a;
}
sort(t+1, t+t[0]+1); sort(d+1, d+d[0]+1);
for (int i=1, j=1; i<=t[0] && j<=d[0]; ) {
double dt=(t[i]-lt)*v + ld;
if (dt<d[j]) lt=t[i++], ld=dt, v=1.0/(++vn);
else if (dt>d[j]) lt+=(d[j]-ld)/v, ld=d[j++], v=1.0/(++vn);
else lt=t[i++], ld=dt, ++j, vn+=2, v=1.0/vn;
if (i>t[0]) {
for (; j<=d[0]; ++j) lt+=(d[j]-ld)/v, ld=d[j], v=1.0/(++vn);
break;
}
if (j>d[0]) {
for (; i<=t[0]; ++i) ld+=(t[i]-lt)*v, lt=t[i], v=1.0/(++vn);
break;
}
}
if (ld<1000.0) lt+=(1000.0-ld)/v;
printf("%.0lf\n", lt);
return 0;
}

C. ssoj2977 流图(flow)

如果一张有向图存在一个点可以到达所有的点,则称这个图是一个流图 (Flow Graph)。现在给定一张有向图,请判断这张图是不是流图;如果是,输出所有的点 \(r\) 满足点 \(r\) 可以到达图中的所有点。\(1\le n,m\le 1000\)。

DFS?!! 注意到不重复 DFS 全图的时间复杂度是 \(O(m)\),所以可以采用 \(O(nm)\) 的极端暴力做法,即以每个点为起点跑 DFS。太暴力了考场上没想出来……

#include <cstdio>
#include <cstring> int n, m, ant, ans[1005];
int head[1005], nex[1005], to[1005];
int v[1005], cnt; inline void add(int x, int y) {
nex[++head[0]]=head[x], head[x]=head[0], to[head[0]]=y;
}
void dfs(int x) {
for (int i=head[x]; i; i=nex[i]) if (!v[to[i]])
++cnt, v[to[i]]=1, dfs(to[i]);
} int main() {
scanf("%d%d", &n, &m);
for (int i=1, a, b; i<=m; ++i)
scanf("%d%d", &a, &b), add(a, b);
for (int i=1; i<=n; ++i) {
memset(v, 0, sizeof v); cnt=1, v[i]=1;
dfs(i); if (cnt==n) ans[++ant]=i;
}
if (!ant) {putchar('0'); return 0; }
printf("%d\n", ant);
for (int i=1; i<=ant; ++i) printf("%d ", ans[i]);
return 0;
}

D. ssoj3146 物品选取

有 \(n\) 件物品,每件物品尺寸为 \(A_i\),价值为 \(B_i\)。令 \(A_\max\) 为所选物品中最大的尺寸,\(A_\min\) 为所选物品中最小的尺寸。令 \(sum\) 为选择物品的价值之和。选择一些物品,使得 \(sum−(A_\max−A_\min)\) 最大。\(2\le n\le 5\times 10^5, 1\le A_i\le 10^{15}, 1\le B_i\le 10^9\)。

容易想到按照 \(A\) 排序,枚举最值。\(sum\) 预处理前缀和。可得 \(O(n^2)\) 做法。显然不是正解。

考虑用算式表示答案:令 \(i\) 为最大值,\(j\) 为最小值,最大化 \(sum(i)-sum(j-1)-A_i+A_j=sum(i)-A_i+A_j-sum(j-1)\)。当前状态答案只与 \(i,j\) 有关。

尺取法。枚举 \(i\),对于每个 \(i\),维护 \(A_j-sum(j-1)\) 的最大值。时间复杂度降为 \(O(n)\)。

#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long int n; ll sum[500003], ans;
struct node {
ll A, B;
bool operator < (const node& a) const {return A<a.A; }
} p[500003]; int main() {
scanf("%d", &n);
for (int i=1; i<=n; ++i) scanf("%lld%lld", &p[i].A, &p[i].B);
sort(p+1, p+n+1);
for (int i=1; i<=n; ++i) sum[i]=sum[i-1]+p[i].B;
ll m=0, t=0;
for (int i=1; i<=n; ++i) {
m=sum[i]-p[i].A;
t=max(t, p[i].A-sum[i-1]);
ans=max(ans, m+t);
}
printf("%lld\n", ans);
return 0;
}

小结

都是简单的做法,但是因为时间复杂度估计失误,不敢于写出来。看来暴力、贪心写得不够多……是啊,既然都是 NOIP 范围内的知识,那怎么区分高手?还是依靠思维难度取胜!

4 November in ss的更多相关文章

  1. 极路由2(极贰)在OpenWrt下定制自己的ss服务

    默认刷入的OpenWrt带的ss, 只有ss-redir服务, 但是在实际使用中, 很多时候还是希望访问直接通过正常网关, 只有少部分访问需要通过ss, 所以希望能配置成为ss-local服务. 在保 ...

  2. 记一次ss故障

    本文主要参考: https://github.com/shadowsocks/shadowsocks shadowssocks 分为客户端和服务器端. 我们平时买的服务,使用是要用的是客户端. 如果你 ...

  3. ss命令和Recv-Q和Send-Q状态

    ss 用来显示处于活动状态的套接字信息.ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比nets ...

  4. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

    java日期格式大全 format SimpleDateFormat(转) SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH ...

  5. SS - DIY一个前端模板引擎.(一)

    前端MVVM 模式有点很多,完全摆脱了意大利面条式的代码. 个人认为,所有MVVM 的框架基础就是一个高性能的JS模板引擎,它极大简化了 DOM 操作, 使页面渲染和业务逻辑彻底分离. 为了理解模板引 ...

  6. YYYY-mm-dd HH:MM:SS

    备忘:YYYY-mm-dd HH:MM:SS部分解释 d               月中的某一天.一位数的日期没有前导零.    dd             月中的某一天.一位数的日期有一个前导零 ...

  7. js 获取当前日期时间3种格式化方法 yyyy-mm-dd hh:MM:ss

    方法一: Date.prototype.format = function (format) { var args = { "M+": this.getMonth() + 1, & ...

  8. 在VPS上搭建SS访问火星

    前段时间发布了Visual Studio 2017 RC,由于现在VS没有离线的ISO了,只有一个在线安装文件.虽然可以通过这个在线安装文件生成完整的离线安装包(之前的ISO版本在安装过程中仍然需要联 ...

  9. 每天一个linux命令(57):ss命令

    ss是Socket Statistics​的缩写.顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的 ...

随机推荐

  1. JSP 学习笔记1

    JSP 学习笔记   JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例--JSP页面有系统编译成Servlet,Servlet再负责响应用户请求. 1.JSP注释 < ...

  2. HTML--JS 二级联动

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. MQ基础知识学习

    之前听人提起了MQ协议,我就去稍微了解了一下什么是MQ,和MQ的一些基础性的知识. 什么是MQ呢? 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据 ...

  4. Stream的排序

    1.list<Integer>的正序 List<Integer> list = new ArrayList<>();list.add(50);list.add(45 ...

  5. 方法重载(overload)与方法重写(override)

    一.方法重载: 在同一个类中,允许存在一个及以上的同名方法,只要他们的参数列表不同(参数的个数或者参数的类型不同)即可.注意方法重载与返回值类型.访问权限修饰符.和抛出的异常无关.重载是在本类中,与继 ...

  6. 洛谷 P1049 装箱问题(01背包)

    一道水题,但看到好久没有发博客了,再一看是一道noip普及组t4,就做了. 题目链接 https://www.luogu.org/problemnew/show/P1049 解题思路 一道裸的01背包 ...

  7. 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)

    题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...

  8. LibreOJ 6177 题解(状压DP)

    题面 传送门 分析 刚看到这道题时想的是跟最短哈密顿路类似的二进制状压DP,先用floyd处理距离 但是此题用二进制不够,应该用三进制 0,1,2分别表示未送,正在送,已送完 dp[s][i]表示当前 ...

  9. CodeForces 219D Choosing Capital for Treeland (树形DP)经典

    <题目链接> 题目大意: 给定一个有向树,现在要你从这颗树上选一个点,使得从这个点出发,到达树上其它所有点所需翻转的边数最小,输出最少需要翻转的边数,并且将这些符合条件的点输出. 解题分析 ...

  10. 如何判断元素是否在可视区域内--getBoundingClientRect

    介绍 Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置. 根据MDN文档 getBoundingClientRect 方法返回的是一个DOMRect ...