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/颜色问题 题解:算一下每个仆人到它的目的地 ...
随机推荐
- 几种远程调用接口协议简单比较和web service(SOAP)与HTTP接口的区别:
什么是web service? 答:soap请求是HTTP POST的一个专用版本,遵循一种特殊的xml消息格式Content-type设置为: text/xml任何数据都可以xml化. ...
- java后台使用HttpURLConnection实现百度主动推送
优点是快 不需要页面执行,,发布文章之后立即推送,所以,不管有没有人访问,都可以自动实时推送 尝试了一下httpclient,没找到相关资料,post方式无法塞url进去 最后改为 import ja ...
- day65——day69
目录 DAY65 课堂笔记 1.vue实例 2.插值表达式 3.文本指令 4.面向对象js 5.js函数补充 6.事件指令 7.属性指令 DAY66 课堂笔记 1.表单指令 2.条件指令 3.循环指令 ...
- 使用Scrapyd部署Scrapy爬虫到远程服务器上
1.准备好爬虫程序 2.修改项目配置 找到项目配置文件scrapy.cnf,将里面注释掉的url解开来 本代码需要连接数据库,因此需要修改对应的数据库配置 其实就是将里面的数据库地址进行修改,变成远程 ...
- 原生js 判断变量是一个数组
const arr = [] // 1. 最简单 ES5+ Array.isArray(arr) // 2. 兼容性好的方法,也很准确 Object.prototype.toString.call(a ...
- BZOJ2120&&2453 数颜色&&维护队列
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1442 Solved: 678 [Submit][Status][Discuss ...
- Linux User and Group Management
linux is a multi-user and multitasking OS. In Linux, you can create any number of user account and g ...
- LUOGU P1937 [USACO10MAR]仓配置Barn Allocation
传送门 解题思路 扫了一眼觉得是贪心+线段树,结果贪心的时候刚开始按区间长度排的序..这还有82分,后来叉了自己,换成按右端点排序过了. 代码 #include<iostream> #in ...
- css3正方体效果
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- JPA实体
Java类可以很容易地转换成实体. 对于实体转换,基本要求是 - 无参数构造函数 注解 @Entity和@Id注解. @Entity - 这是一个标记注释,表明这个类是一个实体.这个注释必须放在类名称 ...