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)不知道厕 ...
随机推荐
- Linux 学习笔记之超详细基础linux命令 Part 10
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 9----------------- ...
- Linux笔记(二): WIN 10 Ubuntu 双系统
(一) 说明 记录一次ubuntu安装过程及遇到的问题. 环境:WIN 10 单硬盘 (二) ubuntu ISO文件下载 ubuntu 18.04 https://www.ubuntu.com/ ...
- 【Python】keras使用Lenet5识别mnist
原始论文中的网络结构如下图: keras生成的网络结构如下图: 代码如下: import numpy as np from keras.preprocessing import image from ...
- ionic入门
ionic安装 Ionic开发是依赖于Nodejs环境的,所以在开发之前我们需要安装好Nodejs.下载安装:http://nodejs.org/安装完成之后打开PowerShell输入命令node ...
- 谷歌浏览器javascript错误提示插件
JavaScript-Errors-Notifier_v2.1.7 下载地址 安装方法: http://chromecj.com/utilities/2014-09/181.html 设置方式:
- 转:SQL Server - 使用 Merge 语句实现表数据之间的对比同步
表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...
- C#中的console类输入输出功能
Console.WriteLine() 直接将括号内内容显示在控制台界面中(相当于C语言printf()吧) Console.ReadLine()获取控制台用户自己输入的内容(功能和C语言scanf( ...
- 4.92Python数据类型之(7)字典
目录 目录 前言 (一)字典的基本知识 ==1.字典的基本格式== (二)字典的操作 ==1.字典元素的增加== ==2.字典值的查找== ==3.字典的修改== ==4.字典的删除== ==5.字典 ...
- python之列表的常用操作
Python list 常用方法总结 一,创建列表 只要把逗号分隔的不同的数据项使用方括号([ ])括起来即可 下标(角标,索引)从0开始,最后一个元素的下标可以写-1 list = ['1 ...
- Hadoop2.7.6_04_HDFS的Shell操作与常见问题
1. HDFS的shell操作 1.1. 支持的命令及参数 [yun@mini05 zhangliang]$ hadoop fs Usage: hadoop fs [generic options] ...