NOIP模拟 7.03
Problem 1 抓牛(catchcow.cpp/c/pas)
【题目描述】
农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来.
他们都站在数轴上.约翰在N(O≤N≤100000)处,奶牛在K(O≤K≤100000)处.约翰有两种办法移动,步行和瞬移:步行每秒种可以让约翰从x处走到x+l或x-l处;而瞬移则可让他在1秒内从x处消失,在2x处出现.然而那只逃逸的奶牛,悲剧地没有发现自己的处境多么糟糕,正站在那儿一动不动.
那么,约翰需要多少时间抓住那只牛呢?
【输入格式】
仅有两个整数N和K
【输出格式】
最短时间
【样例输入】
5 17
【样例输出】
4
【题解】
广搜水过
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- inline void read(int &x){x = ;char ch = getchar();char c = ch;while(ch > '' || ch < '')c = ch, ch = getchar();while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();if(c == '-')x = -x;}
- const int INF = 0x3f3f3f3f;
- const int MAXN = ;
- int n,k;
- int b[MAXN][];
- //状态标号:0:x+1 1:x - 1 2:x * 2
- struct Node
- {
- int x,flag,step;
- }queue[];
- int head,tail;
- int ans;
- inline void bfs()
- {
- //[head, tail]
- if(n >= k)
- {
- ans = n - k;return;
- }
- if((n + == k || n - == k) || ((n << ) == k))
- {
- ans = ;return;
- }
- head = , tail = ;
- queue[++tail] = Node{n - , , };
- queue[++tail] = Node{n + , , };
- queue[++tail] = Node{(n << ), , };
- b[n - ][] = true;
- b[n + ][] = true;
- b[(n << )][] = true;
- register Node tmp;
- while(head <= tail)
- {
- tmp = queue[head ++];
- for(int i = ;i < ;++ i)
- {
- if(i == && tmp.x - >= && !b[tmp.x - ][])
- {
- if(tmp.x - == k)
- {
- ans = tmp.step + ;
- return;
- }
- queue[++tail] = Node{tmp.x - , , tmp.step + };
- b[tmp.x - ][] = true;
- }
- else if(i == && tmp.x + <= && !b[tmp.x + ][])
- {
- if(tmp.x + == k)
- {
- ans = tmp.step + ;
- return;
- }
- queue[++tail] = Node{tmp.x + , , tmp.step + };
- b[tmp.x + ][] = true;
- }
- else if(tmp.x * <= && !b[(tmp.x << )][])
- {
- if((tmp.x << ) == k)
- {
- ans = tmp.step + ;
- return;
- }
- queue[++tail] = Node{(tmp.x << ), , tmp.step + };
- b[(tmp.x << )][] = true;
- }
- }
- }
- }
- int main()
- {
- read(n);read(k);
- bfs();
- printf("%d", ans);
- return ;
- }
Problem 2 路面修整(grading.cpp/c/pas)
【题目描述】
FJ打算好好修一下农场中某条凹凸不平的土路。按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中。 整条路被分成了N段,N个整数A_1, ... , A_N (1 <= N <= 2,000)依次描述了每一段路的高度(0 <= A_i <= 1,000,000,000)。FJ希望找到一个恰好含N个元素的不上升或不下降序列B_1, ... , B_N,作为修过的路中每个路段的高度。由于将每一段路垫高或挖低一个单位的花费相同,修路的总支出可以表示为: |A_1 - B_1| + |A_2 - B_2| + ... + |A_N - B_N| 请你计算一下,FJ在这项工程上的最小支出是多少。FJ向你保证,这个支出不会超过2^31-1。【输入格式】
第1行: 输入1个整数:N * 第2..N+1行: 第i+1行为1个整数:A_i
【输出格式】
第1行: 输出1个正整数,表示FJ把路修成高度不上升或高度不下降的最小花费
【样例输入】
7
1
3
2
4
5
3
9
【样例输出】
3
【样例解释】
FJ将第一个高度为3的路段的高度减少为2,将第二个高度为3的路段的高度增加到5,总花费为|2-3|+|5-3| = 3,并且各路段的高度为一个不下降序列 1,2,2,4,5,5,9。
【题解】
DP题。
【状态定义】
dp[i][j]表示前i个数,最后一个数在原数组中是第j大/小的最小价值。记录cnt[i]为第i大/小得数,num[i]为第i个位置的数
【转移】
dp[i][j] = min{dp[i - 1][k] + abs(num[i] - cnt[j])} 1 <= k <= j
【优化】
1、状态更新是O(n)的,我们可以用mi[i][j]表示dp[i][1..j]的最小值
2、这里还有一个技巧,我们可以让dp[i][j]表示前i个数,最后一个数在原数组中是前j大 的最小价值
转移有
dp[i][j] = min{dp[i][j - 1], dp[i - 1][j] + abs(num[i] - cnt[j])}
同时也可以使用滚动数组进行优化
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- inline int min(int a, int b){return a > b ? b : a;}
- inline void read(int &x){x = ;char ch = getchar();char c = ch;while(ch > '' || ch < '')c = ch, ch = getchar();while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();if(c == '-')x = -x;}
- const int INF = 0x3f3f3f3f;
- const int MAXN = + ;
- int dp[][MAXN], num[MAXN], cnt[MAXN], recnt[MAXN],ans,n;
- int main()
- {
- read(n);
- for(register int i = ;i <= n;++ i)
- {
- read(num[i]);
- recnt[i] = cnt[i] = num[i];
- }
- std::sort(cnt + , cnt + + n);
- std::sort(recnt + , recnt + + n, std::greater<int>());
- register int tmp = ;
- for(register int i = ;i <= n;++ i)
- {
- for(register int j = ;j <= n;++ j)
- {
- if(j == )
- dp[tmp][j] = dp[tmp ^ ][j] + abs(cnt[j] - num[i]);
- else
- dp[tmp][j] = min(dp[tmp][j - ], dp[tmp ^ ][j] + abs(cnt[j] - num[i]));
- }
- tmp ^= ;
- }
- ans = dp[n & ][n];
- tmp = ;
- for(register int i = ;i <= n;++ i)
- {
- for(register int j = ;j <= n;++ j)
- {
- if(j == )
- dp[tmp][j] = dp[tmp ^ ][j] + abs(recnt[j] - num[i]);
- else
- dp[tmp][j] = min(dp[tmp][j - ], dp[tmp ^ ][j] + abs(recnt[j] - num[i]));
- }
- tmp ^= ;
- }
- ans = min(ans, dp[n & ][n]);
- printf("%d", ans);
- return ;
- }
Problem 3 教主的魔法(magic.cpp/c/pas)
【题目描述】
教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。
每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)
CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。M”,则紧接着有三个数字L
WD巨懒,于是他把这个回答的任务交给了你。
【输入格式】
第1行为两个整数N、Q。Q为问题数与教主的施法数总和。
第2行有N个正整数,第i个数代表第i个英雄的身高。
第3到第Q+2行每行有一个操作:
(1)若第一个字母为“、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。
(2)若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。
【输出格式】
对每个“A”询问输出一行,仅含一个整数,表示闭区间 [L, R] 内身高大于等于C的英雄数。
【样例输入】
5 3
1 2 3 4 5
A 1 5 4
M 3 5 1
A 1 5 4
【样例输出】
2
3
【数据范围】
【输入输出样例说明】
原先5个英雄身高为1、2、3、4、5,此时[1, 5]间有2个英雄的身高大于等于4。教主施法后变为1、2、4、5、6,此时[1, 5]间有3个英雄的身高大于等于4。
【数据范围】
对30%的数据,N≤1000,Q≤1000。
对100%的数据,N≤1000000,Q≤3000,1≤W≤1000,1≤C≤1,000,000,000
【题解】
分块+二分模板题,第一次写分块。。常数优化到天际
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- #include <cmath>
- inline void read(int &x){x = ;char ch = getchar();char c = ch;while(ch > '' || ch < '')c = ch, ch = getchar();while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();if(c == '-')x = -x;}
- inline int min(int a, int b){return a < b ? a : b;}
- void put(int x){if (x < )x = ~x + , putchar('-');if (x > ) put(x / );putchar(x % + );}
- const int INF = 0x3f3f3f3f;
- const int MAXN = + ;
- int n,q;
- int squ[MAXN],num[MAXN],pos[MAXN],block,flag[MAXN],size;
- int L[MAXN],R[MAXN];
- //对第x个块进行重新排序
- int resort(int x)
- {
- int l = L[x];
- int r = R[x];
- for(register int i = l;i <= r;++ i)
- squ[i] = num[i];
- std::sort(squ + l, squ + r + );
- }
- //对第x个块快内进行二分查找,返回找到的长度
- int find(int x, int k)
- {
- int l = L[x];
- int r = R[x];
- int last = r;
- int mid;
- while(l <= r)
- {
- mid = (l + r) >> ;
- if(squ[mid] < k)l = mid + ;
- else r = mid - ;
- }
- return last - l + ;
- }
- //区间修改,[ll,rr]增加k
- inline void modify(int ll, int rr, int k)
- {
- //同一个块则暴力修改
- if(pos[ll] == pos[rr])
- {
- for(register int i = ll;i <= rr;++ i)
- num[i] = num[i] + k;
- resort(pos[ll]);
- return;
- }
- //不同的块先改左右两边
- register int l = pos[ll],r = pos[rr];
- if(L[l] < ll)
- {
- for(register int i = ll;i <= R[l];++ i)
- num[i] = num[i] + k;
- resort(l);
- ++ l;
- }
- if(R[r] > rr)
- {
- for(register int i = L[r];i <= rr;++ i)
- num[i] = num[i] + k;
- resort(r);
- -- r;
- }
- for(register int i = l;i <= r;++ i)
- flag[i] = flag[i] + k;
- }
- //区间查询,[ll,rr]查询k
- int ask(int ll, int rr, int k)
- {
- register int ans = ;
- if(pos[ll] == pos[rr])
- {
- for(int i = ll;i <= rr;++ i)
- if(num[i] + flag[pos[i]] >= k)ans ++;
- return ans;
- }
- register int l = pos[ll],r = pos[rr];
- if(L[l] < ll)
- {
- for(register int i = ll;i <= R[l];++ i)
- if(num[i] + flag[pos[i]]>= k)ans ++;
- ++ l;
- }
- if(R[r] > rr)
- {
- for(register int i = L[r];i <= rr;++ i)
- if(num[i] + flag[pos[i]]>= k)ans ++;
- -- r;
- }
- for(register int i = l;i <= r;++ i)
- ans = ans + find(i, k - flag[i]);
- return ans;
- }
- int main()
- {
- read(n);read(q);
- register char c;
- register int tmp1,tmp2,tmp3;
- block = sqrt(n);
- if(n % block)
- size = n / block + ;
- else
- size = n / block;
- for(register int i = ;i <= n;++ i)
- {
- read(num[i]);
- pos[i] = (i - ) / block + ;
- squ[i] = num[i];
- }
- for(register int i = ;i <= size;++ i)
- L[i] = (i - ) * block + ,R[i] = i * block;
- if(R[size] > n)R[size] = n;
- for(register int i = ;i <= size;++ i)
- resort(i);
- for(register int i = ;i <= q;++ i)
- {
- c = getchar();while(c != 'M' && c != 'A')c = getchar();
- read(tmp1);read(tmp2);read(tmp3);
- if(c == 'M')modify(tmp1, tmp2, tmp3);
- else put(ask(tmp1, tmp2, tmp3)), putchar('\n');
- }
- return ;
- }
NOIP模拟 7.03的更多相关文章
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
随机推荐
- CAS企业级单点登录原理
https://blog.csdn.net/anumbrella/article/details/80821486 1. 单点登录概述 1.1. 什么是单点登录? 单点登录:Single Sign O ...
- springMVC和springBoot区别
Spring MVC是什么?(1)Spring MVC是Spring提供的一个强大而灵活的模块式web框架.通过Dispatcher Servlet, ModelAndView 和 View Reso ...
- Cat- Linux必学的60个命令
1.作用 cat(“concatenate”的缩写)命令用于连接并显示指定的一个和多个文件的有关信息,它的使用权限是所有用户. 2.格式 cat [options] 文件1 文件2…… 3.[opti ...
- Centos7解决在同一局域网内无法使用ssh连接
参考: https://www.cnblogs.com/liyuanhong/articles/5785368.html 一.修改网卡设置 nano /etc/sysconfig/network-sc ...
- SQL Server日常积累
1: 在Sql Server 中增加一列语句: alter table table_name add column_name [not null] [references ....] 例 ...
- typeof, offsetof, container_of宏
container_of宏实现如下: #define container_of(ptr, type, member) ({ \ )->member ) *__mptr = (ptr); \ (t ...
- Spring注解驱动开发(二)-----生命周期、属性赋值
bean的生命周期 bean的生命周期:bean创建---初始化----销毁的过程容器管理bean的生命周期:我们可以自定义初始化和销毁方法:容器在bean进行到当前生命周期的时候来调用我们自定义的初 ...
- [C#] 生成 (web): 未能加载文件或程序集“Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7
有时候编译asp.net会遇到奇怪的错误: 生成 (web): 未能加载文件或程序集"Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, ...
- Jeecg-Boot 开发环境准备(二):开发工具安装
目录索引: 后端开发工具 前端开发工具 Nodejs镜像 WebStorm入门配置 JeecgBoot采用前后端分离的架构,官方推荐开发工具 前端开发: Webstrom 或者 IDEA 后端开发: ...
- Luogu P4011 孤岛营救问题(状态压缩+最短路)
P4011 孤岛营救问题 题意 题目描述 \(1944\)年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到 ...