2017NOIP游记
记得去年这个时候,大概刚接触OI。没想到时间这么快,第一次2017NOIP之旅已经结束。初测成绩出来了,100+100+95+50=345,有浙江三十几名(@Cptraser 机房370大佬)。总体感觉还可以吧,也发挥的不错。但有些地方还是有点可惜。学校里的学长(@Cptraser)让我开个博客,我也想谨以此记录一下自己的点滴吧。
贴的都是比赛时的原码
T1 太搞笑的一题,虽然有很多人因为精度爆60(还好手动整数除)
CODE
#include<cstdio>
using namespace std;
int a,b,c;
int main()
{
freopen("score.in","r",stdin); freopen("score.out","w",stdout);
scanf("%d%d%d",&a,&b,&c);
printf("%d",a/+b*/+c/);
return ;
}
T2 感觉今年PJ前两题今年来算是最水的吧,刚开始想打字符串的,后来仔细一想%%%一下就水了
CODE
#include<cstdio>
#include<algorithm>
using namespace std;
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
const int N=;
int n,q,i,j,x,s[N],w;
inline int Pow_10(int k)
{
int tot=;
for (int i=;i<=k;++i)
tot*=;
return tot;
}
int main()
{
freopen("librarian.in","r",stdin); freopen("librarian.out","w",stdout);
read(n); read(q);
for (i=;i<=n;++i)
read(s[i]);
sort(s+,s+n+);
for (i=;i<=q;++i)
{
bool flag=;
read(w); read(x);
for (j=;j<=n;++j)
if (s[j]%Pow_10(w)==x) { printf("%d\n",s[j]); flag=; break; }
if (!flag) puts("-1");
}
return ;
}
T3 从T3开始难度就有提升。BFS很简单;SPFA很简单; 然而我考试时都没想到,对着一个记搜调了2个半小时,导致我T4最后想到了单调队列优化然后没时间了
先贴比赛CODE(158行)
#include<cstdio>
#include<cstring>
using namespace std;
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
const int M=,fx[]={,,,-},fy[]={,,-,},INF=1e9;
int map[M][M],n,m,i,j,x,y,z,ans=1e9,f[M][M][],vis[M][M];
inline int min(int a,int b) { return a<b?a:b; }
void dfs(int x,int y)
{
bool flag=;
if (map[x][y]==) flag=;
for (int i=;i<;++i)
{
int xx=fx[i]+x,yy=fy[i]+y;
if (xx>&&xx<=m&&yy>&&yy<=m&&vis[xx][yy])
{
if (map[xx][yy])
{
if (f[xx][yy][]!=INF)
{
if (flag)
{
int add;
if (map[xx][yy]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add+);
if (map[xx][yy]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add+);
} else
{
int add;
if (map[x][y]==map[xx][yy]) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add);
}
} else
{
vis[xx][yy]=;
dfs(xx,yy);
vis[xx][yy]=;
if (flag)
{
int add;
if (map[xx][yy]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add+);
if (map[xx][yy]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add+);
} else
{
int add;
if (map[x][y]==map[xx][yy]) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add);
}
}
} else
{
if (f[xx][yy][]!=INF&&f[xx][yy][]!=INF)
{
if (!flag)
{
int add;
if (map[x][y]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add);
if (map[x][y]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add);
}
} else
{
if (!flag)
{
vis[xx][yy]=;
dfs(xx,yy);
vis[xx][yy]=;
int add;
if (map[x][y]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add);
if (map[x][y]==) add=; else add=;
f[x][y][]=min(f[x][y][],f[xx][yy][]+add);
}
}
}
}
}
}
void xz()
{
for (int i=;i<=m;++i)
for (int j=;j<=m;++j)
{
if (map[i][j])
{
for (int k=;k<;++k)
{
int x=fx[k]+i,y=fy[k]+j;
if (x>&&x<=m&&y>&&y<=m)
{
if (map[x][y])
{
int add;
if (map[x][y]==map[i][j]) add=; else add=;
f[i][j][]=min(f[i][j][],f[x][y][]+add);
} else
{
int add;
if (map[i][j]==) add=; else add=;
f[i][j][]=min(f[i][j][],f[x][y][]+add);
if (map[i][j]==) add=; else add=;
f[i][j][]=min(f[i][j][],f[x][y][]+add);
}
}
}
} else
{
for (int k=;k<;++k)
{
int x=fx[k]+i,y=fy[k]+j;
if (x>&&x<=m&&y>&&y<=m)
{
if (map[x][y])
{
int add;
if (map[x][y]==) add=; else add=;
f[i][j][]=min(f[i][j][],f[x][y][]+add+);
if (map[x][y]==) add=; else add=;
f[i][j][]=min(f[i][j][],f[x][y][]+add+);
}
}
}
}
}
}
int main()
{
freopen("chess.in","r",stdin); freopen("chess.out","w",stdout);
memset(map,,sizeof(map));
memset(vis,true,sizeof(vis));
read(m); read(n);
for (i=;i<=m;++i)
for (j=;j<=m;++j)
f[i][j][]=f[i][j][]=f[i][j][]=INF;
f[][][]=;
for (i=;i<=n;++i)
{
read(x); read(y); read(z);
map[x][y]=z+;
}
vis[m][m]=;
dfs(m,m);
xz();
bool flag=;
if (map[m][m]==) flag=;
if (flag) { if (min(f[m][m][],f[m][m][])==INF) puts("-1"); else printf("%d",min(f[m][m][],f[m][m][])); }
else { if (f[m][m][]==INF) puts("-1"); else printf("%d",f[m][m][]); }
return ;
}
上面的dfs其实在搞笑,真正得(骗)了95分的是那个最后10分钟加上去的xz(),%%%%%%
回来后仔细想了想,打了个SPFA,就是建边的过程有点烦
对于每个有颜色的点
距离为1的有颜色的点颜色相同连1条0的边;颜色不同连一条1的边;
距离为2的有颜色的点颜色相同连1条2的边;颜色不同连一条3的边;
最后对于(m,m)有无颜色的问题特判一下就过了,代码量明显减少
CODE
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int fx1[]={,,,-},fy1[]={,,-,},fx2[]={,,-,,-,-,,},fy2[]={-,,,,-,,-,};
const int M=;
int map[M][M],INF,father[M*M+],i,x,y,z,n,m,j,dis[M*M+],q[M*M*+],f[M*M+],head,tail;
vector <int> a[M*M+],l[M*M+];
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
void build(int x,int y)
{
for (int i=;i<;++i)
{
int xx=x+fx1[i],yy=y+fy1[i];
if (map[xx][yy]!=INF&&xx>&&yy>&&xx<=m&&yy<=m)
a[(x-)*m+y].push_back((xx-)*m+yy),l[(x-)*m+y].push_back(map[x][y]!=map[xx][yy]);
}
for (int i=;i<;++i)
{
int xx=x+fx2[i],yy=y+fy2[i];
if (map[xx][yy]!=INF&&xx>&&yy>&&xx<=m&&yy<=m)
a[(x-)*m+y].push_back((xx-)*m+yy),l[(x-)*m+y].push_back(map[x][y]==map[xx][yy]?:);
}
}
int main()
{
freopen("chess.in","r",stdin); freopen("chess.out","w",stdout);
read(m); read(n);
memset(map,,sizeof(map));
memset(dis,,sizeof(dis));
for (i=;i<=n;++i)
{
read(x); read(y); read(z);
map[x][y]=z;
}
INF=map[][];
for (i=;i<=m;++i)
for (j=;j<=m;++j)
if (map[i][j]!=INF) build(i,j);
dis[]=; q[]=; f[]=;
head=; tail=;
while (head<tail)
{
int now=q[++head];
f[now]=;
for (i=;i<a[now].size();++i)
{
int k=a[now][i];
if (dis[k]>dis[now]+l[now][i])
{
dis[k]=dis[now]+l[now][i];
if (!f[k])
{
q[++tail]=k;
f[k]=;
}
}
}
}
if (map[m][m]==INF)
{
if (map[m][m-]!=INF) dis[m*m]=min(dis[m*m],dis[m*m-]+);
if (map[m-][m]!=INF) dis[m*m]=min(dis[m*m],dis[m*m-m]+);
}
if (dis[m*m]==INF) puts("-1"); else printf("%d",dis[m*m]);
return ;
}
T4 谨记机房大佬(@Cptraser)的教诲,NOIP已经很久很久没有考MST了。然而今年,一如既往的没考。
最后一题 看一眼 二分答案,check()
再一看 二维DP也许能行 20分钟打好
然后优化第三题去了 然后再也没有回来
比赛CODE
#include<cstdio>
#include<cstring>
typedef long long LL;
using namespace std;
inline void read(LL &x)
{
x=; char ch=getchar(); LL flag=;
while (ch<''||ch>'') { if (ch=='-') flag=-; ch=getchar(); }
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
x*=flag;
}
const LL N=;
struct data
{
LL x,w;
}a[N];
LL n,d,k,i,j,ans=-,sum=,f[N];
inline LL max(LL a,LL b) { return a>b?a:b; }
bool check(LL x)
{
LL left=x<d?d-x:,right=d+x;
for (i=;i<=n;++i)
f[i]=-1e9;
for (i=;i<=n;++i)
for (j=;j<i;++j)
if (a[i].x-a[j].x>=left&&a[i].x-a[j].x<=right)
{
f[i]=max(f[i],f[j]+a[i].w);
if (f[i]>=k) return ;
}
return ;
}
int main()
{
freopen("jump.in","r",stdin); freopen("jump.out","w",stdout);
read(n); read(d); read(k);
for (i=;i<=n;++i)
read(a[i].x),read(a[i].w),sum+=a[i].w>?a[i].w:;
if (sum<k) { puts("-1"); return ; }
if (d==)
{
sum=;
for (i=;i<=n;++i)
{
sum+=a[i].w;
if (sum>=k) { puts(""); return ; }
}
}
a[].x=a[].w=;
LL l=,r=a[n].x;
while (l<=r)
{
LL mid=(l+r)>>;
if (check(mid)) ans=mid,r=mid-; else l=mid+;
}
printf("%lld",ans);
return ;
}
那个 d==1 的特判其实是在搞笑
单调队列的优化还是很好想的
在距离内的加入,距离外的弹出,为了取最大最优值只需要保持队列单调递减即可。
借鉴了洛谷一名大佬的思路
CODE
#include<cstdio>
#include<cstring>
typedef long long LL;
using namespace std;
inline void read(LL &x)
{
x=; char ch=getchar(); LL flag=;
while (ch<''||ch>'') { if (ch=='-') flag=-; ch=getchar(); }
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
x*=flag;
}
const LL N=;
struct data
{
LL x,w;
}a[N];
struct dl
{
LL x,s;
}q[N*+];
LL n,d,k,i,j,ans=-,sum=,f[N],head,tail,now;
inline LL max(LL a,LL b) { return a>b?a:b; }
bool check(LL x)
{
LL left=x<d?d-x:,right=d+x;
for (i=;i<=n;++i)
f[i]=-1e9;
q[].x=q[].s=; head=; tail=-; now=;
for (i=;i<=n;++i)
{
for (now;(a[now].x<=a[i].x-left)&&(now<i);++now)
{
while (head<=tail&&q[tail].s<f[now]) --tail;
if (f[now]==-1e9) continue;
q[++tail].x=a[now].x; q[tail].s=f[now];
}
while (head<=tail&&a[i].x-q[head].x>right) head++;
if (head<=tail) f[i]=q[head].s+a[i].w;
if (f[i]>=k) return ;
}
return ;
}
int main()
{
freopen("jump.in","r",stdin); freopen("jump.out","w",stdout);
read(n); read(d); read(k);
for (i=;i<=n;++i)
read(a[i].x),read(a[i].w),sum+=a[i].w>?a[i].w:;
if (sum<k) { puts("-1"); return ; }
/*if (d==1)
{
sum=0;
for (i=1;i<=n;++i)
{
sum+=a[i].w;
if (sum>=k) { puts("0"); return 0; }
}
}*/
a[].x=a[].w=;
LL l=,r=a[n].x;
while (l<=r)
{
LL mid=(l+r)>>;
if (check(mid)) ans=mid,r=mid-; else l=mid+;
}
printf("%lld",ans);
return ;
}
暑假才P->C,代码有点chou
其实今年的O气真的很足,第三题水了95
感觉今年总体难度比去年低吧,但浙江的分数线才280(据说)……
有点小兴奋吧,毕竟一年的付出没有白费
明年再接再厉,准备下提高吧
顺便宣传下大佬的博客(@Cptraser)http://www.cnblogs.com/Cptraser/
2017NOIP游记的更多相关文章
- 2017NOIP游记 (格式有点炸)
NOIP游记 作者:一只小蒟蒻 时间可真快呀!还记得我第一次接触信息竞赛时,hello world都要调好久,不知不觉就考完了2017noip,自我感觉良好(虽然还是有很多不足). 这两个月的闭关,让 ...
- 2017Noip普及组游记
Day0 一天都基本在休息,早上信心赛,大家都是400整. 下午一群人窝在教室里打三国杀. Day1:Before Contest 早上大约十点到了试场,在考提高组,不能进. 喝了一杯咖啡去除早起的身 ...
- 2017NOIP初赛游记
前天晚上,玩三国杀,玩到了昨天凌晨2点40多分吧,我觉得初赛要爆炸了, 不得不吐槽一下,三国杀的武将太少了. 昨天是初赛的日子,上午8点多来了后看了看阅读程序和程序填空,复习了以下理论知识和wsj 然 ...
- 【20161203-20161208】清华集训2016滚粗记&&酱油记&&游记
先挖坑(这个blog怎么变成游记专用了--) 已更完 #include <cstdio> using namespace std; int main(){ puts("转载请注明 ...
- 【20160722-20160728】NOI2016滚粗记&&酱油记&&游记
先挖坑 #include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs.c ...
- NOIp2016 游记
DAY -2 不要问我为什么现在就开了一篇博客. 本来想起个NOIp2016爆零记或者NOIp2016退役记之类的,但是感觉现在不能乱立flag了.所以就叫游记算了. 前几场模拟赛崩了一场又一场,RP ...
- NOIP2016游记
只是游记而已.流水账. Day0:忘了. Day1:看完T1,本以为T2一如既往很简单,结果看了半天完全没有思路.然后看了一眼T3,期望,NOIP什么时候要考期望了,于是接着看T2.一开始我推的限制条 ...
- CTSC2016&&APIO2016滚粗记&&酱油记&&游记<del>(持续更新)</del>
挖一波坑 #include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs. ...
- 游记——noip2016
2016.11.18 (day 0) 呆在家. 悠闲地呆在家.. 明后天可能出现的错误: 1)没打freopen.打了ctime: 2)对拍程序忘记怎么写了...忘记随机化种子怎么写了: 3)不知道厕 ...
随机推荐
- Vue CLI3 开启gzip压缩
gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度.html.js.css文件甚至json数据都可以用它压缩,可以减小60%以上的体积. webpack在打包时可以借助 compr ...
- winsock编程学习笔记
以下部分转自博客http://blog.csdn.net/phunxm/article/details/5085869 套接字地址(sockaddr.sockaddr_in) /* * Structu ...
- 浅谈 Mysql 中的索引
文章归属:http://feiyan.info/16.html,我想自己去写了,但是发现此君总结的非常详细.直接搬过来了 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基 ...
- [iOS]多线程和GCD
新博客wossoneri.com 进程和线程 进程 是指在系统中正在运行的一个应用程序. 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开QQ.Xcode,系统就会分别 ...
- nodejs在spawn中执行npm报错 [Error: spawn ENOENT]” errors
描述: 上代码 var ps = require('child_process').spawn("npm", ['install'], { stdio: 'inherit', cw ...
- DMA与cache一致性的问题
Cache和DMA本身似乎是两个毫不相关的事物.Cache被用作CPU针对内存的缓存利用程序的空间局部性和时间局部性原理,达到较高的命中率,从而避免CPU每次都必须要与相对慢速的内存交互数据来提高数据 ...
- win10无法删除文件夹(其中的文件或者文件夹已在另一个程序中打开)怎么办?
1. 右键点击任务管理器 2.打开资源监视器 3.搜索任务,结束任务(可能会死机)
- MySQL之慢查询日志分析
在MySQL命令行中查看慢查询日志是否打开了: mysql> show variables like '%slow_query%'; +---------------------------+- ...
- 【Excel】SUMIF函数的兼容性
兼容性非常强的两个函数 SUMIF() 说兼容性,当然得说SUMIF了. 来,我们先举个例子. 现有一个表格,算起来只有"科目划分"."发生额"两列内容,但是折 ...
- 2.2Python数据处理篇之---math模块的数学函数
目录 目录 前言 (一)一览表 1.基本函数 2.对数函数 3.三角函数 4.角度的切换 5.双曲函数 6.math定义的常数 (二)实例 目录 前言 math模块是基础的python数学函数模块,是 ...