【noip 模拟赛curse,light,maze】 题解
2018.10.16
总结:考的不好
原因:
1.考的时候没状态,读题读不进去
2.考的时候不仔细,该得分没得到
T1:curse
1、咒语
(curse.pas/c/cpp)
【题目描述】
亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路。正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条。亮亮拿起纸条的一端,只见上面写着打开机关的方法:“打开机关需要念动符咒,咒语是一串长为 L 的由 0 和 1 组成的字符串。在这张长纸条上列了 n 个长为 L 的字符串,正确的咒语即是在纷繁的 2^L 种字符串中,与这些纸条上的字符串相异度之和最小,并且在满足这一条件下,0的个数最多的字符串。两个字符串的相异度定义为对应位置不相等的字符对的个数。如‘011’和‘001’的相异度为1,因为它们有且只有第二个位置上的字符不相等。”亮亮拉起纸条,只觉得纸条似乎永远也拉不完。这上面有着数以万计的字符串,而每一个字符串的长度也或百或千,以人力看来是无法得到正确的咒语。你能帮帮他,让他得以进入魔法城堡,一窥其中的奥秘吗?
【输入格式】
第一行为一个数字N 。
接下来的N行,每行为一个长为 L 的 01 字符串。数据保证N 个字符串等长。
【输出格式】
只有一行,是一个长为L 的字符串 S,即为正确的咒语。
【样例输入】
4
01011
01001
01101
10111
【样例输出】
01001
【数据规模】
对于 20%的数据,N<=5;
对于 60%的数据,N<=100;
对于 100%的数据,1<=N<=1000,1<=L<=1000。
题解:
细心读题,不难做出正确判断。坑点:注意当n=1时判断的边界。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int num[maxn], n;
char s[maxn];
int main()
{
freopen("curse.in","r",stdin);
freopen("curse.out","w",stdout);
cin>>n;
int len;
for(int i = 1; i <= n; i++)
{
cin>>s;
len = strlen(s);
for(int j = 0; j < len; j++)
if(s[j] == '1') num[j]++;
}
for(int i = 0; i < len; i++)
{
if(num[i] > n/2) cout<<"1";
else cout<<"0";
}
return 0;
}
T2:light
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 的最小值。
【样例输入】
3 1 1
22
1
7
【样例输出】
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大的时候答案就是1。
所以我们把数据范围缩小到2000。
不妨设p[k] 表示使用一次激光发射L距离能摧毁到第几座法坛 ,q[k] 表示使用一次激光发射2*L距离能摧毁到第几座法坛,可以预处理得到p,q
dp[i][j]表示使用i次红光,j次绿光能摧毁最多的法坛数,那么二分返回true的条件是dp[R][G] == n
有状态转移方程:\(dp[i][j] = max(p[dp[i-1][j]+1], q[dp[i][j-1]+1])\)
p[dp[i-1][j]+1] 是红光在dp中前一次到下一次能摧毁的最远
q[dp[i][j-1]+1] 是绿光在dp中前一次到下一次能摧毁的最远
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2018;
int dp[maxn][maxn], a[maxn], p[maxn], q[maxn], R,N,G, ans;
bool check(int L)
{
memset(dp, 0, sizeof(dp));
memset(p, 0, sizeof(p));
memset(q, 0, sizeof(q));
for(int i = 1; i <= N; i++)
for(int j = i; j <= N; j++)
{
if(a[j] - a[i] + 1 <= L) p[i] = j;
if(a[j] - a[i] + 1 <= L*2) q[i] = j;
}
p[N+1] = q[N+1] = N;
for(int i = 0; i <= R; i++)
for(int j = 0; j <= G; j++)
{
if(i > 0) dp[i][j] = max(p[dp[i-1][j]+1], dp[i][j]);
if(j > 0) dp[i][j] = max(q[dp[i][j-1]+1], dp[i][j]);
}
return dp[R][G] == N;
}
int main()
{
freopen("light1.in","r",stdin);
freopen("light.out","w",stdout);
cin>>N>>R>>G;
if(R+G > N)
{
cout<<"1";
return 0;
}
for(int i = 1; i <= N; i++)
cin>>a[i];
sort(a+1, a+1+N);
a[0] = 0;
int l = 1, r = a[N] - a[1] + 1;
while(l <= r)
{
int mid = (l + r) >> 1;
if(check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
cout<<ans;
return 0;
}
T3:maze
3、迷宫
(maze.pas/c/cpp)
【题目描述】
破了魔法阵后,亮亮进入了一座迷宫。这座迷宫叫做“梦境迷宫”,亮亮只有走出这座迷宫,才能从睡梦中醒来。梦境迷宫可以用无向图来表示。它共有 n 个点和 m 条双向道路,每条道路都有边权,表示通过这条道路所需的时间,且每条道路可以多次经过。亮亮位于一号点,而出口则是n号点。原本,亮亮该找到一条最短路,快速冲出迷宫,然而,梦境迷宫的特殊之处在于,如果沿着最短路到达出口,亮亮就会永远陷入梦境。因此,亮亮必须寻找一条次短路。次短路的长度须严格大于最短路(可以有多条)的长度,同时又不大于所有除最短路外的道路的长度。你的任务,就是编写一个程序,帮助亮亮找到通向出口的次短路。
【输入格式】
第一行有两个整数n、m,表示迷宫内共有n 个点,m 条边。
接下来 m行,每行三个整数x、y、z,表示结点 x和 y 之间连有一条边权为
z的无向边。
【输出格式】
一个整数,表示次短路的长度。
【样例输入】
4 4
1 2 2
2 4 4
2 3 3
3 4 4
【样例输出】
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表示无向边的边长。
求次短路。我是傻逼跑了1,n两次spfa后枚举点,枚举边就能过。
因为会有到点n后走回一条最短的边再回去的情况。
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100010;
struct edge{
int len, to, from, next;
}E[maxn<<2];
int cnt, head[maxn];
void add(int u, int v, int w)
{
E[++cnt].from = u;
E[cnt].len = w;
E[cnt].next = head[u];
head[u] = cnt;
E[cnt].to = v;
}
int diss[maxn], dise[maxn], s, e, ans = 0x7fffffff, n, m, now;
bool viss[maxn], vise[maxn];
queue<int> qs, qe;
void SPFAs()
{
memset(diss, 127, sizeof(diss));
memset(viss, 0, sizeof(viss));
qs.push(s);
diss[s] = 0;
viss[s] = 1;
while(!qs.empty())
{
int now = qs.front(); qs.pop();
viss[now] = 0;
for(int i = head[now]; i != -1; i = E[i].next)
{
if(diss[E[i].to] > diss[now] + E[i].len)
{
diss[E[i].to] = diss[now] + E[i].len;
if(!viss[E[i].to])
{
qs.push(E[i].to);
viss[E[i].to] = 1;
}
}
}
}
}
void SPFAe()
{
memset(dise, 127, sizeof(dise));
memset(vise, 0, sizeof(vise));
qe.push(e);
dise[e] = 0;
vise[e] = 1;
while(!qe.empty())
{
int now = qe.front(); qe.pop();
vise[now] = 0;
for(int i = head[now]; i != -1; i = E[i].next)
{
if(dise[E[i].to] > dise[now] + E[i].len)
{
dise[E[i].to] = dise[now] + E[i].len;
if(!vise[E[i].to])
{
qe.push(E[i].to);
vise[E[i].to] = 1;
}
}
}
}
}
int main()
{
memset(head, -1, sizeof(head));
scanf("%d%d",&n,&m);
s = 1, e = n;
for(int i = 1; i <= m; i++)
{
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
add(u, v, w); add(v, u, w);
}
SPFAs();
SPFAe();
for(int i = 1; i <= n; i++)
for(int j = head[i]; j != -1; j = E[j].next)
{
int v = E[j].to, w = E[j].len;
now = diss[i] + dise[v] + w;
if(now < ans && now > diss[n])
ans = now;
}
printf("%d\n",ans);
return 0;
}
附:在poj3255有次短路原题。
//MisakaAzusa
//dsbdsb2003.
【noip 模拟赛curse,light,maze】 题解的更多相关文章
- NOIP模拟赛 打铁的匠 题解
[问题描述] Mark Douglas是一名优秀的锻造师.与他优秀的锻造水平不相符,他非常穷,以至于很多好刀都因为缺少素材缺少资金无法打造. Mark把他有能力锻造的所有n种刀建成了一棵锻造树,除了第 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
- CH Round #48 - Streaming #3 (NOIP模拟赛Day1)
A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...
- CH Round #54 - Streaming #5 (NOIP模拟赛Day1)
A.珠 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/珠 题解:sb题, ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 10.17 NOIP模拟赛
目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
随机推荐
- docker 卸载
1首先搜索已经安装的docker 安装包 [root@localhost ~]# yum list installed|grep docker 或者使用该命令 [root@localhost ~]# ...
- spss C# 二次开发 学习笔记(五)——Spss系统集成模式
Spss官方不支持Server2008R2等Server系列,但做Spss的二次开发,调用Spss的Web系统,一般部署在Server系列上,例如Server2008R2. 起初,在Server上安装 ...
- String拾遗
简介: String作为日常最常用的类,还是有必要对其中的细节做一些了解的,这篇就结合源码来看看这个常用的类. 一. 总述 类图如下: 从图中可以看到String是实现了 java.io.Serial ...
- Hibernate 注解(Annotations 四)多对多双向注解
注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来 ...
- BZOJ1492 [NOI2007]货币兑换
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- Sql语句常用关键字
--语 句 功 能--数据操作SELECT --从数据库表中检索数据行和列INSERT --向数据库表添加新数据行DELETE --从数据库表中删除数据行UPDATE --更新数据库表中的数据 --数 ...
- H5前端正则验证插件
最近学习了一个新的关于前端正则验证的插件,‘jQuery.validate.js ’ 要用这个插件 首先得有插件,下载jquery.validate.min.js 和jq文件并引入. 我把它简单的通俗 ...
- Java设计模式—备忘录模式
个人感觉备忘录模式是一个比较难的设计模式,备忘录模式就是一个对象的备份模式,提供了一种程序数据的备份方法. 定义如下:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以 ...
- CentOS7运维管理笔记(12)----修改主机名
CentOS修改主机名 CentOS7和CentOS6.5 修改主机名的方法略有不同. 通过 hostname 命令可以查看当前的主机名. 1. 临时修改主机名 通过 'hostname 新的主机名' ...
- C# 后台解析json,简单方法 字符串序列化为对象,取值
如果后台是一个JSON的字符串格式如下: string str = "{\"Success\":true,\"Msg\":\"成功!\&qu ...