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. create-react-app 创建项目失败

    创建失败后查阅相关资料,亲测删除 C:\Users\Administrator\AppData\Roaming\npm-cache\ 该文件夹下所有内容后成功.

  2. leyou_07_对数据的操作

    1.目标在数据库的两张表中拿到以下数据,并完成状态.搜索和分页功能 实体类Spu(页面需要的数据) 实体类Category(页面需要的数据) name:商品分类 2.分析: 返回的数据在两个实体类中, ...

  3. 学习mysql数据库

    1.数据库是怎么回事 数据库是存储数据的永久空间,通过一种特殊的方式存储到硬盘中 数据库分为关系型数据库和非关系型数据库 mysql查看数据的方式为:结构化查询语言(SQL语句) 访问mysql数据库 ...

  4. Web充斥着存在漏洞的过期JavaScript库

    虽然使用第三方软件库通常会降低开发的时间,但同时也会增加网站暴露出的攻击表面,对此我们应有充分的认识.因此需要保持第三方软件库的最新版本依赖,以便从安全更新中获益.即便如此,一份近期研究表明,在Ale ...

  5. python-基础-字符串-列表-元祖-字典2

    接上:http://www.cnblogs.com/liu-wang/p/8973273.html 3 元组 4 字典 4.1 字典的介绍 <2>软件开发中的字典 变量info为字典类型: ...

  6. day18-事务与连接池 7.事务隔离级别总结

  7. 2019-8-30-BAT-脚本判断当前系统是-x86-还是-x64-系统

    title author date CreateTime categories BAT 脚本判断当前系统是 x86 还是 x64 系统 lindexi 2019-08-30 08:47:40 +080 ...

  8. 2019-10-11-VisualStudio-配置多进程调试快捷键启动项目

    title author date CreateTime categories VisualStudio 配置多进程调试快捷键启动项目 lindexi 2019-10-11 15:33:32 +080 ...

  9. Leetcode443.String Compression压缩字符串

    给定一组字符,使用原地算法将其压缩. 压缩后的长度必须始终小于或等于原数组长度. 数组的每个元素应该是长度为1 的字符(不是 int 整数类型). 在完成原地修改输入数组后,返回数组的新长度. 进阶: ...

  10. Django定义全局变量

    定义全局变量,在项目的任何位置都可以获取到变量的值 在include App=>include文件夹下=>context_processors.py 里定义需要获取的变量 #!/usr/b ...