2019.6.21 NOIP2018提高组模拟题(二)
1、咒语
(curse.pas/c/cpp)
【题目描述】
亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路。正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条。
亮亮拿起纸条的一端,只见上面写着打开机关的方法:“打开机关需要念动符咒,咒语是一串长为 L 的由 0 和 1 组成的字符串。在这张长纸条上列了 n 个长为 L 的字符串,正确的咒语即是在纷繁的 2^L 种字符串中,与这些纸条上的字符串相异度之和最小,并且在满足这一条件下, 0 的个数最多的字符串。两个字符串的相异度定义为对应位置不相等的字符对的个数。如‘011’和‘001’的相异度为 1,因为它们有且只有第二个位置上的字符不相等。”
亮亮拉起纸条,只觉得纸条似乎永远也拉不完。这上面有着数以万计的字符串,而每一个字符串的长度也或百或千,以人力看来是无法得到正确的咒语。你能帮帮他,让他得以进入魔法城堡,一窥其中的奥秘吗?
【输入格式】
第一行为一个数字 N 。
接下来的 N 行,每行为一个长为 L 的 01 字符串。数据保证 N 个字符串等长。
【输出格式】
只有一行,是一个长为 L 的字符串 S,即为正确的咒语。
【样例输入】
【样例输出】
01001
【数据规模】
对于 20%的数据, N<=5;
对于 60%的数据, N<=100;
对于 100%的数据, 1<=N<=1000, 1<=L<=1000。
题解:
按位模拟每一位对应的数字,p[i][0]:第i位'0'的个数, p[i][1]:第i位'1'的个数。
p[i][0] > p[i][1]时,为保证'字符串相异度之和最小',第i位为'0';
p[i][0] < p[i][1]时,为保证'字符串相异度之和最小',第i位为'1';
p[i][0] = p[i][1]时,为保证'0 的个数最多',第i位为'0';
#include <cstdio>
#include <cstring>
using namespace std;
char ch[];
int n, len, p[][];
int main() {
scanf("%d", &n);
for(int i = ;i <= n;i ++) {
scanf("%s", ch + );
if(len == ) len = strlen(ch + );
for(int j = ;j <= len;j ++) p[j][(ch[j] - '') & ] ++;
}
for(int i = ;i <= len;i ++)
printf("%c", p[i][] >= p[i][] ? '' : '');
return ;
}
2、神光
(light.pas/c/cpp)
【题目描述】
亮亮成功地念出了咒语,石门缓缓地自动移开,一道道绚丽的神光从城堡内激射而出。亮亮好奇而又兴奋地走入了城堡中,迎面有一座极长的魔法阵。
魔法阵可以看作一条直线,它被均匀地分成了 1 000 000 000 个位置,一个位置可以看成是一个格子。有些位置上筑有法坛,一共 N 座。亮亮只有破了眼前的魔法阵,才能继续前进,而欲破法阵,必须毁掉所有的法坛。
亮亮身前有两根法杖:一根颜色血红,能发红色神光,光芒可以笼罩连续 L个位置,并摧毁这 L 个位置上所有的法坛,最多使用 R 次;另一根颜色碧绿,能发绿色神光,光芒可以笼罩连续 2L 个位置,并摧毁这 2L 个位置上所有的法坛,最多使用 G 次。
法杖的神奇之处在于, L 的值必须由亮亮事先设定好,并且一经设定,便无法更改。亮亮需要在规定的次数下摧毁所有法坛,并且使得 L 最小。
【输入格式】
第一行三个整数 N, R, G。
第 i (2<=i<=n+1) 行一个整数 Ai ,表示第 i 座法坛的位置。
【输出格式】
只有一个整数,表示 L 的最小值。
【样例输入】
【样例输出】
4
【样例解释】
亮亮将 L 设为 4,并用红色神光笼罩 21-24 位置,用绿色神光笼罩 1-8 位置。
【数据规模】
对于 50%的数据, N <= 100;
对于 100%的数据, 1 <= N <= 2000, 1 <= R, G, Ai <= 1,000,000,000。
题解:
首先我们注意到,当 R 和 G 的大小超过了 N 时,L 的最小值就是 1,
因此,我们只 需要考虑 R 和 G 小于 N 的情况,于是 R,G 的规模就降到了 2000 以内。 显然要采用二分答案的方法。
那么问题转化为,判断给定的 L 能否摧毁所有法坛,我 们采用动态规划方法。首先将法坛的位置按照从小到大进行排序。
令 dp[i][j]表示,在用了 i 次红光,j 次绿光的情况下,最多从第一座法坛开始,一直摧毁到第几座法坛。
那么状态转 移方程即为 dp[i][j] = max ( P[dp[i-1][j] + 1], Q[dp[i][j-1] + 1] )。
其中 P[k]表示使用一次红光, 能从第 k 座法坛向右(正向为右)连续摧毁到第几座,Q[k]表示使用一次绿光,能从第 k 座 法坛向右连续摧毁到第几座。
P 和 Q 数组可以通过预处理得到。最终,我们只要判断 dp[R][G] 的值是否为 N 即可
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2e3 + ;
int read() {
int x = , f = ; char ch = getchar();
while(ch < ''||ch > '') f = (ch=='-')?-:, ch = getchar();
while(ch >= ''&&ch <= '') x=(x<<)+(x<<)+ch-'', ch = getchar();
return x * f;
}
int n, r, g, a[N], f[N][N], p[N], q[N];
bool check(int x) {
memset(f, , sizeof(f));
memset(p, , sizeof(p));
memset(q, , sizeof(q));
for(int i = ;i <= n;i ++) {
for(int j = i;j <= n;j ++) {
if(a[j] - a[i] + <= x) p[i] = j;
if(a[j] - a[i] + <= x * ) q[i] = j;
}
}
p[n+] = q[n+] = n;
for(int i = ;i <= r;i ++) {
for(int j = ;j <= g;j ++) {
if(i > ) f[i][j] = max(f[i][j], p[f[i-][j]+]);
if(j > ) f[i][j] = max(f[i][j], q[f[i][j-]+]);
}
}
return f[r][g] == n;
}
int main() {
n = read(); r = read(); g = read();
if(n <= r + g) { printf("1\n"); return ; }
for(int i = ;i <= n;i ++) a[i] = read();
sort(a + , a + n + );
int l = , r = 1e9 + ;
while(l < r) {
int mid = (l + r) >> ;
if(check(mid)) r = mid;
else l = mid + ;
}
printf("%d\n", l);
return ;
}
3、迷宫
(maze.pas/c/cpp)
【题目描述】
破了魔法阵后,亮亮进入了一座迷宫。这座迷宫叫做“梦境迷宫”,亮亮只有走出这座迷宫,才能从睡梦中醒来。
梦境迷宫可以用无向图来表示。它共有 n 个点和 m 条双向道路,每条道路都有边权,表示通过这条道路所需的时间,且每条道路可以多次经过。亮亮位于一号点,而出口则是 n 号点。原本,亮亮该找到一条最短路,快速冲出迷宫,然而,梦境迷宫的特殊之处在于,如果沿着最短路到达出口,亮亮就会永远陷入梦境。因此,亮亮必须寻找一条次短路。次短路的长度须严格大于最短路(可以有多条)的长度,同时又不大于所有除最短路外的道路的长度。
你的任务,就是编写一个程序,帮助亮亮找到通向出口的次短路。
【输入格式】
第一行有两个整数 n、 m,表示迷宫内共有 n 个点, m 条边。
接下来 m 行,每行三个整数 x、 y、 z,表示结点 x 和 y 之间连有一条边权为z 的无向边。
【输出格式】
一个整数,表示次短路的长度。
【样例输入】
【样例输出】
9
【样例解释】
最短路: 1 -> 2 -> 4 (长度为 2+4=6)
次短路: 1 -> 2 -> 3 -> 4 (长度为 2+3+4=9)
【数据规模】
对于 100%的数据, 1 <= n <= 5000, 1 <= m <= 100,000。
对于 100%的数据, 1 <= z <= 5000, z 表示无向边的边长。
题解:
次短路模板题:
分别跑两遍 spfa(),
dis[i]: 点i到 1 号点的最短距离;
dis_[i]: 点i到 n 号点的最短距离;
之后, 枚举每条边(共2 * n条边),若x, y分别为这一条边的两个端点,
则dis[i]+dis_[y]+e[i].val即为经过此边的最短路,
在这些边中较 最短路 大的取最小值即可。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = 5e3 + , M = 1e6 + ;
int read() {
int x = , f = ; char ch = getchar();
while(ch < ''||ch > '') f = (ch=='-')?-:, ch = getchar();
while(ch >= ''&&ch <= '') x=(x<<)+(x<<)+ch-'', ch = getchar();
return x * f;
}
int n, m, ans = 2e9 + ;
struct edge { int from, nxt, to, val; } e[M];
int cnt, head[N], dis[N], b[N], dis_[N];
void add(int from, int to, int val) {
e[++ cnt].to = to;
e[cnt].from = from;
e[cnt].val = val;
e[cnt].nxt = head[from];
head[from] = cnt;
}
void spfa() {
queue <int> q; q.push(); b[] = ;
memset(dis, 0x3f, sizeof(dis)); dis[] = ;
while(!q.empty()) {
int tp = q.front(); q.pop(); b[tp] = ;
for(int i = head[tp]; i ;i = e[i].nxt) {
if(dis[e[i].to] > dis[tp] + e[i].val) {
dis[e[i].to] = dis[tp] + e[i].val;
if(! b[e[i].to]) q.push(e[i].to), b[e[i].to] = ;
}
}
}
}
void spfa_() {
memset(b, , sizeof(b));
queue <int> q; q.push(n); b[n] = ;
memset(dis_, 0x3f, sizeof(dis_)); dis_[n] = ;
while(!q.empty()) {
int tp = q.front(); q.pop(); b[tp] = ;
for(int i = head[tp]; i ;i = e[i].nxt) {
if(dis_[e[i].to] > dis_[tp] + e[i].val) {
dis_[e[i].to] = dis_[tp] + e[i].val;
if(! b[e[i].to]) q.push(e[i].to), b[e[i].to] = ;
}
}
}
}
int main() {
n = read(); m = read();
for(int i = , x, y, z;i <= m;i ++)
x = read(), y = read(), z = read(), add(x, y, z), add(y, x, z);
spfa(); spfa_();
for(int i = ;i <= cnt;i ++) {
int len = dis[e[i].from] + dis_[e[i].to] + e[i].val;
if(len > dis[n]) ans = min(ans, len);
}
printf("%d\n", ans);
return ;
}
2019.6.21 NOIP2018提高组模拟题(二)的更多相关文章
- NOIP2018提高组模拟题(五)
字符串(string) Description 小林与亮亮正在做一个游戏.小林随意地写出一个字符串,字符串只由大写 字母组成,然后指定一个非负整数 m,亮亮可以进行至多 m 次操作,每次操作 为交换相 ...
- NOIP2018提高组模拟题(四)
能量(energy) Description 有一块能量田,它的形状是 n*m的矩形,每一个格子上都有一个能量值 a[x][y] (可正可负).一块矩形田的能量定义为它的每个格子的能量值之和. ...
- NOIP2018提高组模拟题(六)
购物(shop) Description 小林来到商店中进行购物.商店里一共有 n 件物品,第 i 件物品的价格为 a[i] 元.小林总共需要购买 m 件物品,他希望他所花费的钱最少,请你计算出最小 ...
- 10.18 NOIP2018提高组模拟题(二)
大水题 1.咒语 (curse.pas/c/cpp) [题目描述] 亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路.正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条. ...
- NOIP2018提高组模拟题(二)
咒语(curse) Description 亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路. 正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条. 亮亮拿起纸条的一端, ...
- 11.5NOIP2018提高组模拟题
书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...
- [JZOJ 5852] [NOIP2018提高组模拟9.6] 相交 解题报告 (倍增+LCA)
题目链接: http://172.16.0.132/senior/#main/show/5852 题目: 题目大意: 多组询问,每次询问树上两条链是否相交 题解: 两条链相交并且仅当某一条链的两个端点 ...
- [JZOJ 5875] [NOIP2018提高组模拟9.20] 听我说,海蜗牛 解题报告(BFS+二分)
题目链接: http://172.16.0.132/senior/#main/show/5875 题目: 题解: 注意这题只能经过开放的港口 我们考虑用vector存下每个点不能到的点,并把并让vec ...
- XJOI——NOIP2015提高组模拟题19-day1——观光旅行
http://www.hzxjhs.com:83/contest/493/problem/3 [题目大意] 给定一个有n(n<=500000)个点,m(1<=500000)条边的无向图.给 ...
随机推荐
- discuz电脑访问手机版域名怎么跳转到电脑版本
用discuz论坛访问手机版本的域名不会自动跳转到电脑版本,而是会跳转到域名+misc.php?mod=mobile体验很不好.现提供修改方法:打开论坛根目录找到文件./source/class/di ...
- delphi 操作xml示例(DelphiBBS)
自:http://www.delphibbs.com/keylife/iblog_show.asp?xid=20713 ======================================== ...
- 图像滤镜艺术---流行艺术风滤镜特效PS实现
原文:图像滤镜艺术---流行艺术风滤镜特效PS实现 今天,本人给大家介绍一款新滤镜:流行艺术风效果,先看下效果吧! 原图 流行艺术风效果图 上面的这款滤镜效果是不是很赞,呵呵,按照本人以往的逻辑,我会 ...
- vs2017 cordova js 签名配置
在build.json文件中添加如下 { "android": { "release": { "keystore": "C:\\D ...
- Selenium 获取动态js的网页
Selenium基于webkit实现爬虫功能 http://www.cnblogs.com/luxiaojun/p/6144748.html https://www.cnblogs.com/chenq ...
- ARTS 1.21 - 1.25
每周一个 Algorithm,Review 一篇英文文章,总结一个工作中的技术 Tip,以及 Share 一个传递价值观的东西! Algorithm: 学习算法 题目:3Sum Closest 解题过 ...
- Android零基础入门第87节:Fragment添加、删除、替换
前面一起学习了Fragment的创建和加载,以及其生命周期方法,那么接下来进一步来学习Fragment的具体使用,本期先来学习Fragment添加.删除.替换. 一.概述 在前面的学习中,特别是动态加 ...
- C# mysql set和enum属性字段的读取和添加
1.使用Navicat for Mysql设置set和enum属性字段: a.enum类型 b.set类型 enum类型在创建表时需要设置初始值,在如图所示的位置设置. 2.C#读取和添加数据 a.e ...
- QT5.8 VS2017 编译教程(可以使用VS2017 XP兼容包)
1.下载QT5.8源码 这个我不做过多解释. 2.安装使用的环境 visual studio 2017 Python Perl Ruby 安装好,并配置好环境PATH变量. 3.修改错误代码 错误 ...
- 深入windows的关机消息截获-从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可Block的时间从1秒调到了5秒) good
之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡.之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时 ...