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/颜色问题 题解:算一下每个仆人到它的目的地 ...
随机推荐
- create-react-app 创建项目失败
创建失败后查阅相关资料,亲测删除 C:\Users\Administrator\AppData\Roaming\npm-cache\ 该文件夹下所有内容后成功.
- leyou_07_对数据的操作
1.目标在数据库的两张表中拿到以下数据,并完成状态.搜索和分页功能 实体类Spu(页面需要的数据) 实体类Category(页面需要的数据) name:商品分类 2.分析: 返回的数据在两个实体类中, ...
- 学习mysql数据库
1.数据库是怎么回事 数据库是存储数据的永久空间,通过一种特殊的方式存储到硬盘中 数据库分为关系型数据库和非关系型数据库 mysql查看数据的方式为:结构化查询语言(SQL语句) 访问mysql数据库 ...
- Web充斥着存在漏洞的过期JavaScript库
虽然使用第三方软件库通常会降低开发的时间,但同时也会增加网站暴露出的攻击表面,对此我们应有充分的认识.因此需要保持第三方软件库的最新版本依赖,以便从安全更新中获益.即便如此,一份近期研究表明,在Ale ...
- python-基础-字符串-列表-元祖-字典2
接上:http://www.cnblogs.com/liu-wang/p/8973273.html 3 元组 4 字典 4.1 字典的介绍 <2>软件开发中的字典 变量info为字典类型: ...
- day18-事务与连接池 7.事务隔离级别总结
- 2019-8-30-BAT-脚本判断当前系统是-x86-还是-x64-系统
title author date CreateTime categories BAT 脚本判断当前系统是 x86 还是 x64 系统 lindexi 2019-08-30 08:47:40 +080 ...
- 2019-10-11-VisualStudio-配置多进程调试快捷键启动项目
title author date CreateTime categories VisualStudio 配置多进程调试快捷键启动项目 lindexi 2019-10-11 15:33:32 +080 ...
- Leetcode443.String Compression压缩字符串
给定一组字符,使用原地算法将其压缩. 压缩后的长度必须始终小于或等于原数组长度. 数组的每个元素应该是长度为1 的字符(不是 int 整数类型). 在完成原地修改输入数组后,返回数组的新长度. 进阶: ...
- Django定义全局变量
定义全局变量,在项目的任何位置都可以获取到变量的值 在include App=>include文件夹下=>context_processors.py 里定义需要获取的变量 #!/usr/b ...