NOIP2017普及复赛 (~~题解)
来源:互联网 发布:java导入自己的package 编辑:程序博客网 时间:2024/06/09 20:24
感觉这一次普及难度很ZZ啊。。。
怎么说呢,考差了(最后一题忘记写朴素DP丢了50分),第三题的BFS也写错了一个if(问题不大),总之,思路上没有问题,主要还是代码能力的问题。。继续加油吧
T1
T1 智障难度。。。只要会编程应该都会做吧。。。我们就跳过此题
T2
又是ZZ难度,嗯,普及T2,一发模拟就可以水过,数据范围
代码:
# include<cstdio># include<cstring># include<algorithm>using namespace std;const int N = 1e3 + 10;struct node{ int val,len;}a[N];int n,q,i,pre,len,ans;bool cmp(node a,node b){ return a.val < b.val;}int getans(int a,int b,int len){ int val = 0,sum = 1; while (len--) { val += (a % 10) * sum; a /= 10; sum *= 10; } if (val == b) return 1; else return 0;}int main(){ scanf("%d%d",&n,&q); for (i = 1;i <= n; i++) { scanf("%d",&a[i].val); int tmp = a[i].val; len = 0; while (tmp) { len++; tmp /= 10; } a[i].len = len; } sort(a + 1,a + n + 1,cmp); for (i = 1;i <= q; i++) { scanf("%d%d",&len,&pre); ans = -1; for (int j = 1;j <= n; j++) { if (a[j].len < len) continue; if (getans(a[j].val,pre,len)) { ans = a[j].val; break; } } printf("%d\n",ans); } return 0;}
T3
难度终于上来了啊,然而这道题呢一眼最短路 or BFS,那么怎么做呢,首先考虑每个格子有颜色,我们可以想到分层图SPFA,对于不同颜色,边长为1,相同颜色边长为0,颜色为白色的,我们可以将它转换成两个点,一个黄点,一个红点,分别转移,但是我们在转移的时候记得if判一下上一次有没有用魔法。BFS同理,BFS我们设一个标记数组,代表走到某个格子是什么颜色的最小花费,然后推队列就行了(打标记的if这里考场ZZ写错了),然后注意一下细节。
代码:
# include<cstdio># include<cstring># include<algorithm>using namespace std;const int N = 1e2 + 10;struct node{ int x,y,cost,col,p;}q[N * N * 500];int a[N][N],bz[N][N][4],dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};int n,m,i,ans;int main(){ memset(bz,0x3f,sizeof(bz)); scanf("%d%d",&m,&n); for (i = 1;i <= n; i++) { int x,y,tmp; scanf("%d%d%d",&x,&y,&tmp); ++tmp; a[x][y] = tmp; } int h = 1,t = 1; bz[1][1][a[1][1]] = 0; q[h] = (node){1,1,0,a[1][1],0}; while (h <= t) { node now = q[h++]; for (i = 0;i < 4; i++) { int x1 = now.x + dir[i][0],y1 = now.y + dir[i][1]; if (x1 < 1 || x1 > m || y1 < 1 || y1 > m) continue; if (!a[x1][y1] && now.p) continue; if (a[x1][y1] == now.col) { int col = now.col; int cost = now.cost; if (cost >= bz[x1][y1][col]) continue; bz[x1][y1][col] = cost; q[++t] = (node){x1,y1,cost,col,0}; }else if (a[x1][y1] != now.col && a[x1][y1] != 0) { int col = a[x1][y1]; int cost = now.cost + 1; if (cost >= bz[x1][y1][col]) continue; bz[x1][y1][col] = cost; q[++t] = (node){x1,y1,cost,col,0}; }else if (a[x1][y1] == 0 && now.p == 0) { int col = 1;int cost = now.cost + 2; if (col != now.col) ++cost; if (cost < bz[x1][y1][col]) //这里注意不要直接continue,不然下个点不能转移,考场这里打错了。。。 { bz[x1][y1][col] = cost; q[++t] = (node){x1,y1,cost,col,1}; } col++; cost = now.cost + 2; if (col != now.col) ++cost; if (cost >= bz[x1][y1][col]) continue; bz[x1][y1][col] = cost; q[++t] = (node){x1,y1,cost,col,1}; } } } ans = min(bz[m][m][1],bz[m][m][2]); if (ans > 2 * m * m) puts("-1"); else printf("%d\n",ans); return 0;}
T4
此次普及比较厉害的一道题,那么我们题目中直接求有两个最值,一般我们不能直接得到两个最小值,由于题目说我们是能不能到K分,那么很容易想到判定性问题,所以用二分求最小值,DP求最高分然后check。。怎么DP呢,我们可以设f[i]表示跳到i的时候能够得到的最高分,然后两个for循环,找符合范围的可转移的状态,那么这么做的复杂度是
代码:
# include<cstdio># include<cstring># include<algorithm>using namespace std;const int N = 5e5 + 10;struct node{ int dis,val;}a[N];int f[N],q[N];int n,k,d,maxx;bool check(int x,int xia){ int h = 1,t = 1,ans = 0,i = 0,fir; f[0] = q[1] = 0; for (i = 1;a[i].dis < xia && i <= n; i++) continue; //前面有一些格子的距离小于下界,则是无法跳到,直接去除 fir = i; for (;i <= n; i++) { if (a[i].dis - a[i - 1].dis > (x + d)) break; //如果和前面一个格子距离已经大于上界了,则直接break就好了,后面的肯定都不能转移。 while (a[i].dis - a[fir].dis >= xia && fir < i) { while (h <= t && f[q[t]] < f[fir]) t--; q[++t] = fir++; } while (h <= t && a[i].dis - a[q[h]].dis > (x + d)) h++; if (h > t) f[i] = -0x3f3f3f3f; //当前格子跳不到 else f[i] = f[q[h]] + a[i].val; ans = max(ans,f[i]); } return ans >= k;}int main(){ scanf("%d%d%d",&n,&d,&k); for (int i = 1;i <= n; i++) scanf("%d%d",&a[i].dis,&a[i].val); int l = 0,r = a[n].dis,ret = 0; while (l <= r) { int mid = (l + r) >> 1; if (check(mid,max(d - mid,1))) r = mid - 1,ret = mid; else l = mid + 1; } if (check(ret,max(d - ret,1))) printf("%d\n",ret); else puts("-1"); return 0;}
- NOIP2017普及复赛 (~~题解)
- NOIP2017普及组复赛题解
- NOIP2017普及组复赛 T1
- NOIP2017普及组复赛T2
- NOIP2017普及组复赛总结
- NOIP2017普及组复赛 T3
- NOIP2017普及组复赛 总结
- NOIP2017普及组题解
- NOIP2017普及组题解
- NOIP2017普及组题解
- noip2016普及组复赛题解
- NOIP2017普及组复赛解题报告
- NOIP2017普及组T1题解
- NOIP2017普及组T2题解
- NOIP-2016-普及组 复赛题解
- [NHZXOI2017]2016NOIP普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(1)NOIP2010普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(2)NOIP2011普及组复赛题解
- 截取指定字符串(指针指向)
- <span>中显示文字超出宽度如何自动隐藏
- 实验吧笔记-IPC$管道攻击与防御方法
- Java 利用Xstream注解生成和解析xml
- Hive Metastore 和hive-server2配置
- NOIP2017普及复赛 (~~题解)
- 单片机编程规范,模块化编程
- Android 自定义Camera全屏拍照,支持前后摄像头
- 内联框架跳转页面
- spark学习-32-SparkEnv的构造步骤
- MyBatis框架
- PythonStock(12):使用python,pandas进行股票分析
- Java学习——StringBuffer和StringBuilder类
- HDU1970 John(经典尼姆博奕)