期望得分: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=,tot=;
for(int i=;i<=n+;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=;i<=n;i++) scanf("%d",&a[i]);
int l=,r=L,mid;
a[n+]=L;
while(l<=r)
{
mid=l+r>>;
if(check(mid)) ans=mid,l=mid+;
else r=mid-;
}
printf("%d",ans);
}

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[],b[];
int f[][][][];
const int mod=;
int main()
{
scanf("%d%d%d",&n,&m,&p);
scanf("%s%s",a+,b+);
f[][][][]=f[][][][]=;
for(int i=;i<=n;i++)
{
int t=i%;
for(int j=;j<=min(i,m);j++)
for(int k=;k<=min(j,p);k++)
{
f[t][j][k][]=(f[t^][j][k][]+f[t^][j][k][])%mod;
if(a[i]==b[j]) f[t][j][k][]=((f[t^][j-][k-][]+f[t^][j-][k-][])%mod+f[t^][j-][k][])%mod;
else f[t][j][k][]=;
}
ans=(ans+f[t][m][p][])%mod;
}
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, k;
long long f[][][], s[][][];
char a[], b[];
const int mod = ;
int main()
{
scanf("%d%d%d", &n, &m, &k);
scanf("%s", a + );
scanf("%s", b + );
int now = , last = ;
f[][][] = ;
for (int i = ; i <= n; i++)
{
f[now][][] = ;
for (int j = ; j <= min(i,m); j++)
for (int kk = ; kk <= min(j,k); kk++)
{
if (a[i] == b[j])
s[now][j][kk] = (s[last][j - ][kk] + f[last][j - ][kk - ]) % mod;
else
s[now][j][kk] = ;
f[now][j][kk] = (f[last][j][kk] + s[now][j][kk]) % mod;
}
swap(now, last);
}
printf("%lld\n", f[last][m][k]);
return ;
}

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*],to[N*],tot,w[N*];
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]+;
dfs(to[i]);
son[x]+=son[to[i]];
}
}
void dfs2(int x,int top)
{
id[x]=++cnt;
bl[x]=top;
int y=;
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,,sizeof(sum));
int h=;
for(int i=;i<=m;i++)
{
if(e[i].dis<=k) continue;
sum[e[i].s]++; sum[e[i].t]++; sum[e[i].lca]-=;
h++;
}
dfs3();
for(int i=;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=;i<n;i++)
{
scanf("%d%d%d",&u,&v,&a);
add(u,v,a);
add(v,u,a);
}
for(int i=;i<=m;i++) scanf("%d%d",&e[i].s,&e[i].t);
dfs();
dfs2(,);
for(int i=;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]-*dis[e[i].lca];
maxn=max(maxn,e[i].dis);
}
r=maxn;
while(l<=r)
{
mid=l+r>>;
if(check(mid)) { ans=mid; r=mid-;}
else l=mid+;
}
printf("%d",ans);
}

NOIP 2015 提高组 Day2的更多相关文章

  1. NOIP 2015提高组复赛

    神奇的幻方 题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第 ...

  2. noip 2015 提高组

    算是填个坑吧 , QwQ Day 1 第一题很水,就是考代码能力 ,直接贴代码. #include <iostream> #include <cstdlib> #include ...

  3. noip 2013 提高组 Day2 部分题解

    积木大赛: 之前没有仔细地想,然后就直接暴力一点(骗点分),去扫每一高度,连到一起的个数,于是2组超时 先把暴力程序贴上来(可以当对拍机) #include<iostream> #incl ...

  4. NOIP 2015 提高组 Day1

    期望得分:100+100+100=300 实际得分:100+100+45=245 T3 相似的代码 复制过去 没有改全,痛失55分 http://www.cogs.pro/cogs/page/page ...

  5. NOIP 2013 提高组 day2 积木大赛

      积木大赛 描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为1的积木组成,第

  6. noip 2012 提高组 day2 部分题解

    这道题有多种解法,我用的是扩展欧几里得算法求到的答案 #include<iostream> #include<fstream> #include<cstdio> u ...

  7. NOIP 2014 提高组 Day2

    期望得分:100+60+30=190 实际得分:70+60+30=160 https://www.luogu.org/problem/lists?name=&orderitem=pid& ...

  8. NOIP 2008提高组第三题题解by rLq

    啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们 ...

  9. [NOIp 1998 提高组]Probelm 2 连接多位数【2011百度实习生笔试题】

    /*====================================================================== [NOIp 1998 提高组]Probelm 2 连接 ...

随机推荐

  1. 20181023-10 Alpha阶段第2周/共2周 Scrum立会报告+燃尽图 07

    作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2290 Scrum master:范靖旋 一.小组介绍 组长:王一可 组员: ...

  2. DataGridView,Dataset,DataTable,DataRow等使用心得

    DataGridView的列编辑: Name:用于调用属性的时候用的,也可以不使用Name去调用,选择数字1,2,3...选择第1列,第2列,第3列. HeaderText:表头显示的名字方便用户使用 ...

  3. 2018软工实践—Alpha冲刺(7)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 学习MSI.CUDA 试运行软件并调试 ...

  4. C++ Primer Plus学习:第七章

    C++入门第七章:函数-C++的编程模块 函数的基本知识 要使用C++函数,必须完成如下工作: 提供函数定义 提供函数原型 调用函数 库函数是已经定义和编译好的函数,可使用标准库头文件提供原型. 定义 ...

  5. python接口自动化测试框架实现之字符串插入变量(字符串参数化)

    问题: 在做接口自动化测试的时候,请求报文是json串,但是根据项目规则必须转换成字符串,然后在开头拼接“data=” 接口中很多入参值需要进行参数化. 解决方案: 1.Python并没有对在字符串中 ...

  6. css3 flex属性flex-grow、flex-shrink、flex-basis学习笔记

    最近在研究css3的flex.遇到的flex:1;这一块,很是很纠结,flex-grow.flex-shrink.flex-basis始终搞不清,最经搜集了大量的介绍,应该能算是明白了.网上大部分解释 ...

  7. Tomcat安装及配置详解

    Tomcat安装及配置详解   一,Tomcat简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat是Apache 软件基金会(Apache Software Found ...

  8. 使用ResourceBundle 类读取 src 下的 xxx.properties 文件

    之前要读取 src 下的 .properties 文件都是使用的类加载器,加载类路径下的资源文件当做一个流来处理,load 到一个 Properties 对象上. jdbc.properties 代码 ...

  9. CPU测试--通过proc获取CPU信息

    adb shell cat /proc/stat | grep cpu > totalcpu0 此处第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了.下表解析第一行 ...

  10. 【数据库】Mysql更改默认引擎为Innodb的步骤方法

    前言 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定. 基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.M ...