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的更多相关文章

  1. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  2. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  3. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  4. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  5. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  6. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  7. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  8. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  9. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

随机推荐

  1. 几种远程调用接口协议简单比较和web service(SOAP)与HTTP接口的区别:

    什么是web service?       答:soap请求是HTTP POST的一个专用版本,遵循一种特殊的xml消息格式Content-type设置为: text/xml任何数据都可以xml化. ...

  2. java后台使用HttpURLConnection实现百度主动推送

    优点是快 不需要页面执行,,发布文章之后立即推送,所以,不管有没有人访问,都可以自动实时推送 尝试了一下httpclient,没找到相关资料,post方式无法塞url进去 最后改为 import ja ...

  3. day65——day69

    目录 DAY65 课堂笔记 1.vue实例 2.插值表达式 3.文本指令 4.面向对象js 5.js函数补充 6.事件指令 7.属性指令 DAY66 课堂笔记 1.表单指令 2.条件指令 3.循环指令 ...

  4. 使用Scrapyd部署Scrapy爬虫到远程服务器上

    1.准备好爬虫程序 2.修改项目配置 找到项目配置文件scrapy.cnf,将里面注释掉的url解开来 本代码需要连接数据库,因此需要修改对应的数据库配置 其实就是将里面的数据库地址进行修改,变成远程 ...

  5. 原生js 判断变量是一个数组

    const arr = [] // 1. 最简单 ES5+ Array.isArray(arr) // 2. 兼容性好的方法,也很准确 Object.prototype.toString.call(a ...

  6. BZOJ2120&&2453 数颜色&&维护队列

    2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1442 Solved: 678 [Submit][Status][Discuss ...

  7. 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 ...

  8. LUOGU P1937 [USACO10MAR]仓配置Barn Allocation

    传送门 解题思路 扫了一眼觉得是贪心+线段树,结果贪心的时候刚开始按区间长度排的序..这还有82分,后来叉了自己,换成按右端点排序过了. 代码 #include<iostream> #in ...

  9. css3正方体效果

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  10. JPA实体

    Java类可以很容易地转换成实体. 对于实体转换,基本要求是 - 无参数构造函数 注解 @Entity和@Id注解. @Entity - 这是一个标记注释,表明这个类是一个实体.这个注释必须放在类名称 ...