HGOI NOIP模拟4 题解
NOIP国庆模拟赛Day5 题解
T1 马里奥
题目描述
马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 NOIP的考场。
从一座浮空岛出发,马里奥可以到达一个在水平方向和这个浮空岛相接的另一个浮空岛,他还可以使用梯子到达在这个浮空岛正上方或正下方的另一座浮空岛,但是这两个浮空岛的高度差不能超过梯子的长度。
现在,马里奥希望用最短的梯子到达传送门,请你输出梯子的最短长度。
我们把浮空岛抽象成一个二维平面,’#’代表浮空岛,’_’代表空中。
两个整数 x,y 代表传送门所在的行数和列数。
保证最下方一行全部为’#’,且传送门所在位置为’#’,
马里奥一开始在最左下方的那个浮空岛上。
输入格式
第一行两个整数 n,m,表示输入平面的行数和列数。
接下来 n 行每行一个包含 m 个字符的字符串,表示这个二维平面。
最后一行两个整数 x,y 表示传送门所在的行和列。
输出格式
输出一行一个整数,表示梯子的最小长度
样例输入输出
Simple input #1:
5 8
####____
___#_###
###__#__
______#_
########
2 4
Simple output#1:
2
数据范围和提示
对于 70%的数据:1≤n,m≤100,1≤x≤n,1≤y≤m。
对于 100%的数据:1≤n,m≤1,000,1≤x≤n,1≤y≤m。
本题时限1s,空间256MB
题解
Subtask1: 暴力dfs不优化暴力(具体不知道多暴力,反正我这个就是最暴力了)
Subtask2: 二分答案+BFS
时间复杂度 O(log n * n^2)
没什么好说了吧
代码(Subtask2 100pts)
# include<bits/stdc++.h>
# define Rint register int
using namespace std;
const int MAXN=1e3+;
int n,m,tt=;
char s[MAXN];
int a[MAXN][MAXN],x,y;
struct rec{ int x,y;};
bool vis[MAXN][MAXN];
bool check(Rint Mid)
{
queue<rec>q;
rec s; s.x=n; s.y=;
q.push(s);
memset(vis,false,sizeof(vis));
while (!q.empty()) {
rec u=q.front();q.pop(); rec v;
if (u.x==x&&u.y==y) return true;
v.x=u.x;v.y=u.y-;
if (v.x>=&&v.x<=n&&v.y>=&&v.y<=m&&a[v.x][v.y]&&(!vis[v.x][v.y])) {
if (v.x==x&&v.y==y) return true;
vis[v.x][v.y]=;
q.push(v);
}
v.x=u.x;v.y=u.y+;
if (v.x>=&&v.x<=n&&v.y>=&&v.y<=m&&a[v.x][v.y]&&(!vis[v.x][v.y])) {
if (v.x==x&&v.y==y) return true;
vis[v.x][v.y]=;
q.push(v);
}
for (int i=;i<=Mid;i++) {
v.x=u.x+i; v.y=u.y;
if (v.x>=&&v.x<=n&&v.y>=&&v.y<=m&&a[v.x][v.y]&&(!vis[v.x][v.y])) {
if (v.x==x&&v.y==y) return true;
vis[v.x][v.y]=;
q.push(v);
}
v.x=u.x-i; v.y=u.y;
if (v.x>=&&v.x<=n&&v.y>=&&v.y<=m&&a[v.x][v.y]&&(!vis[v.x][v.y])) {
if (v.x==x&&v.y==y) return true;
vis[v.x][v.y]=;
q.push(v);
}
}
}
return false;
}
int main()
{
freopen("mario.in","r",stdin);
freopen("mario.out","w",stdout);
scanf("%d%d\n",&n,&m);
for(Rint i=;i<=n;i++) {
cin>>s;
int len=strlen(s);
for (Rint j=;j<len;j++)
if (s[j]=='#') a[i][j+]=;
else a[i][j+]=;
}
scanf("%d%d",&x,&y);
int L=,R=n,Ans;
while (L<=R) {
int M=(L+R)/;
if (check(M)) Ans=M,R=M-;
else L=M+;
}
printf("%d\n",Ans);
return ;
}
T2 祭司
题目描述
马里奥在你的帮助下成功地进入了传送门,但在传送途中,传送门出了一些 故障,马里奥被传送到了一座宏伟的神殿。神殿的祭司愿意帮助马里奥修复传送 门,但是祭司现在正忙于解读古代的魔法典籍,他希望马里奥能帮他解读。古代 典籍中给出了一些变量,每个变量都有一个可能的取值范围,祭司需要把这些变 量分成两组。对于一种划分方案,对这两组变量分别求和之后做差,可能得到的 差值的绝对值的最大值就是这次划分的评级。而那个评级最小的划分是解密的关 键,祭司想让马里奥求出这个最小的评级是多少,但马里奥已经没有多少时间了, 于是他找到了你来帮忙算出这个数字。
输入格式
第一行一个整数 n,表示给出的变量个数。
接下来 n 行每行两个整数,
第 i 行的两个数 li,ri,表示第 i 个变量的取值范围 为[li, ri]。
输出格式
输出应该包含一行一个整数,表示评级的最小值。
输入输出样例
Simple input:
4
1 3
3 6
2 4
4 5
Simple output:
5
Explain:
第一和第四个变量一组,第二和第三个变量一组。
当四个变量分别取值为 (1,6,4,4)时取得该情况下的最大值 5。
数据规模和约定
对于 70%的数据:1≤n≤10。
对于 100%的数据:1≤n,m≤200;0≤li,ri≤200。
本题时限1s,空间256MB
题解:
Subtask1:理解题意暴力dfs
时间复杂度O(2^n)
代码(Subtask1 70pts):
# include <bits/stdc++.h>
using namespace std;
const int MAXN=2e2+;
int n,t[MAXN],ans;
struct rec{
int l,r;
}a[MAXN];
void check()
{
int t1,t2,Max=; t1=t2=;
for (int i=;i<=n;i++)
if (t[i]) t1+=a[i].l;
else t2+=a[i].r;
Max=max(Max,abs(t1-t2));
t1=t2=;
for (int i=;i<=n;i++)
if (t[i]) t1+=a[i].r;
else t2+=a[i].l;
Max=max(Max,abs(t1-t2));
ans=min(ans,Max);
}
void dfs(int dep)
{
if (dep==n+) { check(); return; }
t[dep]=; dfs(dep+);
t[dep]=; dfs(dep+);
}
int main()
{
freopen("priest.in","r",stdin);
freopen("priest.out","w",stdout);
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d%d",&a[i].l,&a[i].r);
ans=INT_MAX;
dfs();
printf("%d\n",ans);
return ;
}
Subtask2:Dp
Min1 表示A集合的上界之和
Min2 表示B集合的上界之和
Max1 表示A集合的下界之和
Max2 表示B集合的下界之和
Sum1 表示A集合元素上下界之和
Sum2 表示B集合元素上下界之和
答案就是求 max(|Min1-Max2|,|Min2-Max1|)
max(|Min1-Max2|,|Min2-Max1|)=max(|Min1+Max1-Max2-Max1|,|Max2+Min2-Max1-Max2|)
=max(|Sum1-(Max1+Max2)|,|Sum2-(Max1+Max2)|);<--最小化这个
其中 Max1+Max2为全集的上界,只需要维护Sum1,Sum2即可.
f[i]表示A集合上下界为i是否可能
f[i]=f[i]|f[i-(a[j].l+a[j].r)];
复杂度O(n^3)
代码(Subtask 2 100pts):
/*
Min1 表示A集合的上界之和
Min2 表示B集合的上界之和
Max1 表示A集合的下界之和
Max2 表示B集合的下界之和
Sum1 表示A集合元素上下界之和
Sum2 表示B集合元素上下界之和
答案就是求 max(|Min1-Max2|,|Min2-Max1|)
max(|Min1-Max2|,|Min2-Max1|)=max(|Min1+Max1-Max2-Max1|,|Max2+Min2-Max1-Max2|)
=max(|Sum1-(Max1+Max2)|,|Sum2-(Max1+Max2)|);<--最小化这个
其中 Max1+Max2为全集的上界,只需要维护Sum1,Sum2即可.
f[i]表示A集合上下界为i是否可能
f[i]=f[i]|f[i-(a[j].l+a[j].r)];
*/
# include <bits/stdc++.h>
using namespace std;
const int MAXN=;
struct rec{
int l,r;
}a[MAXN];
bool f[],n;
int main()
{
scanf("%d",&n);
int Sum1=,Sum2=;
for (int i=;i<=n;i++) {
scanf("%d%d",&a[i].l,&a[i].r);
Sum1+=a[i].l; Sum2+=a[i].r;
}
memset(f,false,sizeof(f));
f[]=true;
for (int i=;i<=n;i++)
for (int j=;j>=a[i].l+a[i].r;j--)
f[j]=f[j]||f[j-a[i].l-a[i].r];
int ans=INT_MAX;
for (int i=;i<=;i++) {
if (!f[i]) continue;
ans=min(ans,max(abs(Sum1-i),abs(Sum2-i)));
}
printf("%d\n",ans);
return ;
}
T3 AK
题目描述
NOIP 考场上,马里奥顺利地切掉了前两题,他只要再切掉最后一题就可以 AK 了。最后一题是这样的:给你一个数字序列,每次查询一段区间的数字和, 并且把它们都变成原来的平方。马里奥瞬间就切掉了这道题,但他觉得这道题对 于别人来说太难了。出题人在和马里奥商量后,决定在询问时只要求返回模一个 数 c = 2305843008676823040 的结果。作为另一名 NOIP 选手的你也已经切掉了 前两题,你能够解决这个修改后的问题,顺利 AK 吗?
输入格式
第一行两个整数 n,m,表示数字个数和询问个数。
接下来一行 n 个数字 ai,表示序列的初始值。
接下来 m 行,每行两个整数 l,r 表示询问区间。
输出格式
对于每次询问,你需要输出一个整数,表示对应询问的结果。
输入输出样例
Simple input:
4 4
2 3 4 5
1 2
2 3
3 4
1 4
Simple output:
5
数据规模和约定
对于 60%的数据:1≤n,m≤2^10。
对于 100%的数据:1≤n,m≤2^16;0≤ai<c。
本题时限5s,空间256MB
题解
我的分块的第一题!!!
首先发现这个东西2305843008676823040明显不是质数
考虑到luogu的某一题模数是2的几次方,也不是质数在这里做手脚
又考虑到luogu有一道上帝造题的七分钟,几次以后就不变了,
由此联想最终发现若干次(考场上用不是质数推发现28次)以后模c的值就不变了
于是想到分块+并查集 维护一个暴力。
Sum[i] 表示第i个块所有值之和,L[i]表示块i的左边界,R[i]表示块i的右边界
a[i].val表示i点的点权,a[i].bl表示i在哪个块里 bl是块的数目
并查集维护i点的右边那个还未被更新的点的位置,便于快速移动
然后register int 还有inline 快读心里作用就可以极限数据1s以内了。
这道题时限5s好像稳过
Subtask 2 100pts)
# include <bits/stdc++.h>
# define int long long
# define Rint register long long
using namespace std;
const int mo=,E=,MAXN=(<<)+;
int n,m,bl;
int f[MAXN],L[MAXN],R[MAXN],sum[MAXN],cnt[MAXN];
struct rec{
int bl,val;
}a[MAXN];
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void print(Rint x)
{
if(x>) print(x/);
putchar(x%+'');
}
inline int father(Rint x)
{
if (f[x]==x) return f[x];
f[x]=father(f[x]);
return f[x];
}
inline int mul(Rint a,Rint b)
{
int res=0ll;
while (b) {
if (b&) res=(res+a)%mo;
a=(a<<)%mo; b>>=;
}
return res%mo;
}
inline int solve(Rint l,Rint r)
{
int lb=a[l].bl,rb=a[r].bl,ans=0ll;
if (lb==rb) {
for (Rint i=l;i<=r;i++)
ans=(ans+a[i].val)%mo;
return ans;
}
for (Rint i=l;i<=R[lb];i++) ans=(ans+a[i].val)%mo;
for (Rint i=r;i>=L[rb];i--) ans=(ans+a[i].val)%mo;
for (Rint i=lb+;i<=rb-;i++) ans=(ans+sum[i])%mo;
return ans%mo;
}
inline void update(Rint l,Rint r)
{
for (Rint i=l;i<=r;i=father(i+)) {
if (i>r||i==) break;
int nowbl=a[i].bl;
sum[nowbl]=(sum[nowbl]-a[i].val+mo)%mo;
a[i].val=mul(a[i].val,a[i].val)%mo; cnt[i]++;
if (cnt[i]>E) f[i]=father(i+);
sum[nowbl]=(sum[nowbl]+a[i].val)%mo;
}
}
signed main()
{
freopen("ak.in","r",stdin);
freopen("ak.out","w",stdout);
scanf("%lld%lld",&n,&m);
for (Rint i=;i<=n;i++) f[i]=i;
memset(cnt,,sizeof(cnt));
bl=; L[]=;
int POA=sqrt(n)+;
for (Rint i=;i<=n;i++) {
if (i%POA==) { R[bl]=i-; bl++; L[bl]=i; }
a[i].val=read();
a[i].bl=bl;
sum[bl]=(sum[bl]+a[i].val)%mo;
}
R[bl]=n;
Rint l,r;
while (m--) {
l=read();r=read();
print(solve(l,r)); putchar('\n');
update(l,r);
}
return ;
}
From: HGOI
Name:ljc20020730
Date: 20181005
HGOI NOIP模拟4 题解的更多相关文章
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- HZOJ 20190818 NOIP模拟24题解
T1 字符串: 裸的卡特兰数题,考拉学长讲过的原题,就是bzoj3907网格那题,而且这题更简单,连高精都不用 结论$C_{n+m}^{n}-C_{n+m}^{n+1}$ 考场上10min切掉 #in ...
- 「题解」NOIP模拟测试题解乱写I(29-31)
NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...
- [NOIP模拟13]题解
A.矩阵游戏 其实挺水的? 考场上根本没有管出题人的疯狂暗示(诶这出题人有毛病吧这么简单的东西写一大堆柿子),而且推公式能力近乎没有,所以死掉了. 很显然乘法有交换率结合率所以操作顺序对最终结果没什么 ...
- 8.3 NOIP 模拟12题解
话说这次考试T1和T2是真的水,然而T1CE,T2TLE,T3CE 这不就是在侮辱我的智商啊!之前本机编译都是c++,以后要用c++11. 这次的T1就是一个大型找规律,我的规律都找出来了,但是竟然用 ...
- HZOJ 20190819 NOIP模拟26题解
考试过程: 照例开题,然后觉得三道题都挺难,比昨天难多了(flag×1),T1 dp?T2 数据结构? T3 dp?事实证明我是sb然后决定先搞T2,但是,woc,这题在说什么啊,我怎么看不懂题啊,连 ...
- [NOIP模拟26]题解
今天的考试题改自闭了……所以滚来写陈年题解. A.*****贪婪***** RT,出题人告诉我们这题要贪心. 最优的策略一定是拖到必须断的时候再断开(虽然并不知道为什么). 如果一段序列满足题目中的性 ...
- [NOIP模拟25]题解
A.字符串 Catalan数不能再裸了 #include<cstdio> #include<iostream> #include<cstring> using na ...
随机推荐
- Cloud Container Service experimentation
Cloud Container Service experimentation K8S技术社区 举办云容器技术动手工作坊 活动时间:2018年1月13日(周六)13:30-17:30 活动地点:北京海 ...
- 大数据入门第十四天——Hbase详解(二)基本概念与命令、javaAPI
一.hbase数据模型 完整的官方文档的翻译,参考:https://www.cnblogs.com/simple-focus/p/6198329.html 1.rowkey 与nosql数据库们一样, ...
- c# 无边框窗体的边框阴影
Windows API: using System; using System.Collections.Generic; using System.ComponentModel; using Syst ...
- jQuery.bsgrid
http://thebestofyouth.com/bsgrid/ 支持json.xml数据格式,皮肤丰富并且容易定制,支持表格编辑.本地数据.导出参数构建等实用便捷的功能,容易扩展,更拥有丰富的示例 ...
- 20155204《网络对抗》Exp7 网络欺诈防范
20155204<网络对抗>Exp7 网络欺诈防范 一.基础问题回答 1.通常在什么场景下容易受到DNS spoof攻击 在不安全的网络环境下访问网站. 2.在日常生活工作中如何防范以上两 ...
- 2017-2018-2 20155224『网络对抗技术』Exp5:MSF基础应用
基础问题回答 用自己的话解释什么是exploit,payload,encode? exploit就相当于是载具,将真正要负责攻击的代码传送到靶机中,我觉得老师上课举的火箭和卫星的例子非常形象,火箭只是 ...
- Java通过pinyin4j实现汉字转拼音
碰到个需求,需要按用户名字的首字母来排序.这就需要获取汉字对应的拼音了,突然就想起了pinyin4j这个jar包,于是就开始写了个汉字转拼音的工具类.在此记录一下,方便后续查阅 一.Pom依赖 ...
- WPF 简易进度条效果
最近做一个项目,看到以前同事写的进度条效果不错,所以,拿来简化了下,不炫,但是项目中还是够用的. 还是,先来看下调用以后的效果 1.因为ProgressbBar的Foreground显示不得不一样,所 ...
- libgdx学习记录20——多线程MultiThread资源处理
在libgdx中,一般的逻辑流程都在rende()函数中执行,这个函数是由opengl的渲染线程调用的,一般的图形显示和逻辑处理都在这个线程中. 一般情形下,在这个线程中处理就行了.但是当某些逻辑处理 ...
- SpringBoot整合EHcache学习笔记
为了提高系统的运行效率,引入缓存机制,减少数据库访问和磁盘IO.下面说明一下ehcache和SpringBoot整合配置 前言介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特 ...