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 ...
随机推荐
- Android之基于小米天气的天气源库
大概去年的这个时候,有跟大家分享简洁天气这个应用. 该应用一開始使用的是中国天气网的数据,可是,由于须要反复多次请求server获取信息才干满足我们的需求,因此.后来我偷偷的将天气源更换成" ...
- Delphi 10.3 Rio + iOS 12.1 SDK 编译错误 "libcharset.1.dylib"
环境版本: Delphi 10.3 Rio iOS 12.1 SDK Xcode 10.1 (10B61) 错误讯息:[DCC Error] E2597 ld: file not found: /us ...
- 20155238 2016-2017-2 《JAVA程序设计》第九周学习总结
教材学习内容总结 第十六章 JDBC SQL的解决方案是JDBC,在Java中,JDBC API主要用来存取数据库. *JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关 ...
- 20155330 《网络对抗》 Exp7 网络欺诈防范
20155330 <网络对抗> Exp7 网络欺诈防范 基础问题回答 通常在什么场景下容易受到DNS spoof攻击 连接局域网的时,特别是在商场或是别的公众较多的场合连接的免费WIFI. ...
- Partition3:分区切换(Switch)
在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...
- SpringBoot中使用Quartz笔记
Quartz可以用来做什么? Quartz是一个任务调度框架,可用来做定时任务. 吧啦吧啦......... 还是直接上代码. application.properties 配置文件. * * ? ...
- let和const----你所不知道的JavaScript系列(2)
let 众所周知,在ES6之前,声明变量的关键字就只有var.var 声明变量要么是全局的,要么是函数级的,而无法是块级的. var a=1; console.log(a); console.log( ...
- First day for introducing me
""" This is first python3 script code for lyp in Bokeyuan __author__="lyp" ...
- [Unity]制作游戏中名字板的过程记录
先大概说一下需求: 1 每个模型上都要有名字板:人.怪.npc等等. 2 名字板上会显示:名字(文字).血条(图片)等 3 因为是透视相机,名字板离得太近会变得超大,且主角移动,名字板的位置相对于相机 ...
- Apache服务器出现Forbidden 403错误提示的解决方法总结
在配置Linux的 Apache服务时,经常会遇到http403错误,我今天配置测试时也出现了,最后解决了,总结了一下.http 403错误是拒绝访问的意思,有很多原因的.还有,这些问题在win平台的 ...