期望得分:100+10+60=170

实际得分:100+10+35=145

http://www.cogs.pro/cogs/page/page.php?aid=16

T1 跳石头

时间限制:1 s   内存限制:256 MB

【题目描述】

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选

择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终 点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达 终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳 跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能 移走起点和终点的岩石)。

【输入格式】

输入文件第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终 点之间的岩石数,以及组委会至多移走的岩石数。

接下来 N 行,每行一个整数,第 i 行的整数 Di(0 < Di < L)表示第 i 块岩石与 起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同 一个位置。

【输出格式】

输出文件只包含一个整数,即最短跳跃距离的最大值。

【样例输入】

25 5 2
2
11
14
17
21

【样例输出】

4

【提示】

输入输出样例 1 说明:将与起点距离为 2 和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。

另:对于 20%的数据,0 ≤ M ≤ N ≤ 10。 对于50%的数据,0 ≤ M ≤ N ≤ 100。

对于 100%的数据,0 ≤ M ≤ N ≤ 50,000,1 ≤ L ≤ 1,000,000,000。

二分最短距离

如果两块石头间距离比二分的还要短,

若 此时还能移走石头,移走

否则return false

#include<cstdio>
#define N 50011
using namespace std;
int L,n,m,ans;
int a[N];
bool check(int k)
{int last=0,tot=0;for(int i=1;i<=n+1;i++) if(a[i]-a[last]<k) {if(tot<m) tot++; else  return false;}else last=i;return true;
}
int main()
{scanf("%d%d%d",&L,&n,&m);for(int i=1;i<=n;i++) scanf("%d",&a[i]);int l=0,r=L,mid;a[n+1]=L;while(l<=r){mid=l+r>>1;if(check(mid)) ans=mid,l=mid+1;else r=mid-1;}printf("%d",ans);
}

View Code

T2 子串
时间限制:1 s   内存限制:128 MB

【题目描述】

有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。

【输入格式】

第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问题描述中所提到的 k,每两个整数之间用一个空格隔开。 第二行包含一个长度为 n 的字符串,表示字符串 A。 第三行包含一个长度为 m 的字符串,表示字符串 B。

【输出格式】

输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输出答案对 1,000,000,007 取模的结果。

【样例输入1】

6 3 1
aabaab
aab

【样例输出1】

2

【样例输入2】

6 3 2
aabaab
aab

【样例输出2】

7

【样例输入3】

6 3 3
aabaab
aab

【样例输出1】

7

【提示】

对于第 1 组数据:1≤n≤500,1≤m≤50,k=1;

对于第 2 组至第 3 组数据:1≤n≤500,1≤m≤50,k=2;

对于第 4 组至第 5 组数据:1≤n≤500,1≤m≤50,k=m;

对于第 1 组至第 7 组数据:1≤n≤500,1≤m≤50,1≤k≤m;

对于第 1 组至第 9 组数据:1≤n≤1000,1≤m≤100,1≤k≤m;

对于所有 10 组数据:1≤n≤1000,1≤m≤200,1≤k≤m。

令 f[i][j][k][0/1]表示A串前i个,分为k部分,匹配B串前j个,A串第i个不用/用 的方案数

状态转移方程:

如果i不用,那他就是前i-1个的和  f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]

如果i用,条件是a[i]=b[j] 那么它有2种决策:自成一堆,与前一个合为一堆

自成一堆的话,他的前一个可能用了,也可能没用,又分为了两种

所以 f[i][j][k][1]= f[i-1][j-1][k-1][1](自成一堆,前一个用了)

+ f[i-1][j-1][k-1][0] (自成一堆,前一个没用)

+ f[i-1][j-1][k][1] (与前一个合为一堆,前一个必须用了)

边界条件:f[i][0][0][0]=1

边界研究了一晚上

f数组累积的前提是 a串中的第i个与b串的第一个相等

这时第i个只能自成一堆,f[i-1][1-1][k-1][0] = 1

最后用滚动数组滚动起来就A了

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,p,ans,s;
char a[1001],b[201];
int f[2][1001][201][2];
const int mod=1000000007;
int main()
{scanf("%d%d%d",&n,&m,&p);scanf("%s%s",a+1,b+1);f[0][0][0][0]=f[1][0][0][0]=1;for(int i=1;i<=n;i++){int t=i%2;for(int j=1;j<=min(i,m);j++)for(int k=1;k<=min(j,p);k++){f[t][j][k][0]=(f[t^1][j][k][0]+f[t^1][j][k][1])%mod;if(a[i]==b[j])   f[t][j][k][1]=((f[t^1][j-1][k-1][0]+f[t^1][j-1][k-1][1])%mod+f[t^1][j-1][k][1])%mod;else f[t][j][k][1]=0;}ans=(ans+f[t][m][p][1])%mod;}
}

View Code

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, k;
long long f[2][205][205], s[2][205][205];
char a[1005], b[205];
const int mod = 1000000007;
int main()
{scanf("%d%d%d", &n, &m, &k);scanf("%s", a + 1);scanf("%s", b + 1);int now = 1, last = 0;f[0][0][0] = 1;for (int i = 1; i <= n; i++){f[now][0][0] = 1;for (int j = 1; j <= min(i,m); j++)for (int kk = 1; kk <= min(j,k); kk++){if (a[i] == b[j])s[now][j][kk] = (s[last][j - 1][kk] + f[last][j - 1][kk - 1]) % mod;elses[now][j][kk] = 0;f[now][j][kk] = (f[last][j][kk] + s[now][j][kk]) % mod;}swap(now, last); }printf("%lld\n", f[last][m][k]);return 0;
}

View Code

T3 运输计划

时间限制:1 s   内存限制:256 MB

【题目描述】

公元 2044 年,人类进入了宇宙纪元。

L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球。

小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物

流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道 是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之 间不会产生任何干扰。

为了鼓励科技创新,L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小 P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。

在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后, 这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的 物流公司的阶段性工作就完成了。

如果小 P 可以自由选择将哪一条航道改造成虫洞,试求出小 P 的物流公司完成阶段 性工作所需要的最短时间是多少?

【输入格式】

第一行包括两个正整数 n、m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。

接下来 n-1 行描述航道的建设情况,其中第 i 行包含三个整数 ai, bi 和 ti,表示第i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。 接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj 号星球。

【输出格式】

共 1 行,包含 1 个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

【样例输入】

6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5

【样例输出】

11

【提示】

所有测试数据的范围和特点如下表所示

请注意常数因子带来的程序效率上的影响。

所需 技能:二分、lca、树链剖分、树上差分

求最值,很容易想到二分,那么我们就二分这个值k

如果最短时间为k,那么如果一个计划耗时超过k,那么它所经过的路径上就要有虫洞

可能有不止一个计划耗时超过k,

那么有可能改造为虫洞的路径是 所有超时的计划路径的交集

如果这个交集中有一条路径,耗时>= 超出的时间(即不建虫洞的最大耗时-二分值)

那么把他改为虫洞可以使时间减少

现在就差如何求 计划耗时 和 交集

计划耗时:树链剖分求lca,同时求出点到根节点的距离dis

计划耗时=dis[起点]+dis[终点]-2*dis[lca]

交集:树上差分

计划起点+1,终点+1,lca-2

然后从叶子节点向上累加

若点的sum等于超时计划数,则点与父节点之间的边在交集中

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define N 300001
using namespace std;
int n,m,l,r,mid,ans,maxn;
int front[N],nextt[N*2],to[N*2],tot,w[N*2];
int son[N],fa[N],dis[N],deep[N];
int id[N],bl[N],cnt;
int sum[N];
struct node
{int s,t,lca,dis;
}e[N];
void add(int u,int v,int x)
{to[++tot]=v; nextt[tot]=front[u]; front[u]=tot; w[tot]=x;
}
void dfs(int x)
{son[x]++;for(int i=front[x];i;i=nextt[i]){if(to[i]==fa[x]) continue;fa[to[i]]=x;dis[to[i]]=dis[x]+w[i];deep[to[i]]=deep[x]+1;dfs(to[i]);son[x]+=son[to[i]];}
}
void dfs2(int x,int top)
{id[x]=++cnt;bl[x]=top;int y=0;for(int i=front[x];i;i=nextt[i]){if(to[i]==fa[x]) continue;if(son[to[i]]>son[y]) y=to[i];}if(!y) return;dfs2(y,top);for(int i=front[x];i;i=nextt[i]){if(to[i]==fa[x]||to[i]==y) continue;dfs2(to[i],to[i]);}
}
void dfs3(int x)
{for(int i=front[x];i;i=nextt[i]){if(to[i]==fa[x]) continue;dfs3(to[i]);sum[x]+=sum[to[i]];}
}
int get_lca(int x,int y)
{while(bl[x]!=bl[y]){if(deep[bl[x]]<deep[bl[y]]) swap(x,y);x=fa[bl[x]];}if(deep[x]>deep[y]) x=y;return x;
}
bool check(int k)
{memset(sum,0,sizeof(sum));int h=0;for(int i=1;i<=m;i++){if(e[i].dis<=k) continue;sum[e[i].s]++; sum[e[i].t]++; sum[e[i].lca]-=2;h++;}dfs3(1);for(int i=1;i<=n;i++) if(sum[i]==h&&dis[i]-dis[fa[i]]>=maxn-k) return true;return false;
}
int main()
{/*freopen("transport.in","r",stdin);freopen("transport.out","w",stdout);*/scanf("%d%d",&n,&m);int u,v,a;for(int i=1;i<n;i++) {scanf("%d%d%d",&u,&v,&a);add(u,v,a);add(v,u,a);}for(int i=1;i<=m;i++) scanf("%d%d",&e[i].s,&e[i].t);dfs(1);dfs2(1,0);for(int i=1;i<=m;i++) {e[i].lca=get_lca(e[i].s,e[i].t);e[i].dis=dis[e[i].s]+dis[e[i].t]-2*dis[e[i].lca];maxn=max(maxn,e[i].dis);}r=maxn;while(l<=r){mid=l+r>>1;if(check(mid)) { ans=mid; r=mid-1;}else l=mid+1;}printf("%d",ans);
}

View Code

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/6750111.html

NOIP 2015 提高组 Day2相关推荐

  1. NOIP 2015 提高组 初赛

    NOIP 2015 提高组 初赛 疑难点 学习 感悟. 一. 3. 示例如下(来自自个的理解): 101.101 十进制 转十进制1*10^2+0*10^1+1*10^0+1*10^-1+0*10^- ...

  2. NOIP 2011 提高组 Day2 校模拟 7.11

    数论只会GCD 模拟只会猜题意 贪心只能过样例!!!!! 上午身体不适,基本上是强行趴在那写题.也不知道思路在哪个状态,看到T1第一想法居然连暴力都不是了.第一想法,居然是打表2333 T1: 计算系 ...

  3. NOIP2011提高组day2

    NOIP 2011 提高组 Day 2 T1 : 题意: 这道题题意很显然,方法就是利用数学中的二项式定理 : ( x + y ) ^ n = C ( i , n ) * x ^ i * y ^ ( ...

  4. NOIP 2018提高组复赛C/C++试题及答案详解

    NOIP 2018提高组历年真题 CCF NOIP2018 初赛提高组 C++语言试题 第 1 页,共9 页 第二十四届全国青少年信息学奥林匹克联赛初赛 提高组 C++语言试题 竞赛时间:2018 年 ...

  5. [NOIP 2013提高组]转圈游戏 题解

    这题在洛谷上是道黄题,即[普及/提高-] 所以虽然是提高组的,但是其实挺简单的. 我们来看下题面: [NOIP 2013]转圈游戏 刚看到题面作为一个蒟蒻感觉它都不配做黄题,但是直到我看清楚了后发现它 ...

  6. NOIP 2013 提高组 货车运输

    描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多 ...

  7. NOIP 2008 提高组 复赛 message 传字条

    NOIP 2008 提高组 复赛 message 传字条 1.样例很快模拟成功,但感觉是凑出来的,没有章法. 2.深度优先遍历,但感觉容易超时. 3.动态规划?翻看他人代码,发现动态规划的写法,确实想 ...

  8. NOIP 2015 普及组 初赛

    NOIP 2015 普及组 初赛 疑难点 学习 感悟. 本份试卷本人得分93,两处错误,一错在二.1.题,眼花了,多数了个数据3241:二错在四.2.题(5)空,该空写成rbound=mid-1,这个 ...

  9. NOIP 2017 提高组 初赛

    NOIP 2017 提高组 初赛 做题感悟. 五.完善程序,是本张试卷最简单的题目,两道题做完,大约花了10分钟.2017-10-17 18:25 对了答案,破天荒,全对. 1.(大整数除法) 有如下 ...

最新文章

  1. Ubuntu 系统安装Visual Studio Code
  2. 机器学习中的标量、向量、矩阵、和张量的概念
  3. 万引大佬自曝这样被MIT拒掉:“系里不喜欢你”,找校长对峙后悟了
  4. java网络编程的通信原理_11 - 网络编程之设备间通信原理
  5. linux 开机启动文件夹,Linux开机启动流程
  6. SQL读书笔记_With Clause的注意事项
  7. Nacos源码覆盖实例列表
  8. 第一弹!安利10个让你爽到爆的IDEA必备插件!
  9. Connected to the target VM, address: '127.0.0.1:60885', transport: 'socket'
  10. Unity3D(六)光照系统
  11. C#获取cpu序列号 硬盘ID 网卡硬地址以及操作注册表 .
  12. CTF中各种好用的软件以及解密网址合集
  13. 打开IIS管理器命令cmd
  14. 解决System进程占用80端口的问题
  15. MySQL之SQL语句实现将三个查询结果集拼接成一个表
  16. 查询结果按中文拼音顺序排序
  17. 李彦宏高中全国计算机比赛,中国互联网“男神”李彦宏学生时代的那些事
  18. 人脑词典、亡者归来……来看库兹韦尔对于未来的四个疯狂预测
  19. Beyond Compare实现Class文件对比
  20. Vue3 tailwindui

热门文章

  1. python实验八分支语句_python语句(分支,循环)
  2. RTX5 | 线程管理01 - 创建线程(静态堆栈方式)
  3. Java学习之文件操作
  4. 学什么c语言标准,C语言的标准 “输入输出”!今天是你学C语言的第几天?
  5. sklearn tfidf求余弦相似度_【基础算法 】文本相似度计算
  6. C++笔记-基于邻接表的BFS(宽度优先遍历)
  7. Web前端笔记-two.js画三角形及画tip含tip旋转
  8. 达梦工作笔记-使用达梦客户端创建用户并授予权限
  9. Java文档阅读笔记-EJB Tutorial
  10. Qt工作笔记-进程间的通信(通过QSharedMemory)