山东多校联合模拟赛 day1
题不难
rect
【问题描述】
给出圆周上的 N 个点, 请你计算出以这些点中的任意四个为四个角,能构成多少个矩形。
点的坐标是这样描述的, 给定一个数组 v[1..N], 假设圆心为(0, 0), 圆的周长 C=∑v[1..N] , 第一个点坐标为(0, C/(2π))。 从第一个点开始, 顺时针沿圆周走 v1 个单位长度,此时坐标为第二个点的坐标,再走 v2 个单位长度,此时为第三个点的坐标,当走完 v1, v2..vi个距离后,为第 i+1 个点的坐标(全过程都是沿圆周顺时针)。 特别的, 走完 v1, v2..vn 个距离后, 就会回到第一个点。
【输入】
输入文件名为 rect.in。
输入共 N+1 行。
第一行为正整数 N。
接下来 N 行每行一个正整数。 其中第 i+1 行表示的是 v[i]。
【输出】
输出文件名为 rect.out。
输出共 1 行,一个整数,表示能构成的矩形的个数。
【输入样例1】
8
1
2
2
3
1
1
3
3
【输出样例1】
3
【数据范围】
对于 100%的数据,有 N<=20, V 数组中的所有元素的值<=100。
【题解】
由于所有的点在圆上,所以可以处理出这些点能组成多少个直径。最后答案为C(直径数量,2)。由于N特别小,处理就是枚举端点即可。如果N是100万,可以考虑维护两个指针处理直径。
ancestor
【问题描述】
任何一种生物的 DNA 都可以表示为一个由小写英文字母组成的非空字符串。科学家发现,所有的生物都有可能发生变异。所谓变,就是子代的 DNA 串与父代的 DNA 串有差异。每次变异, DNA 串中恰好有一个字符会变成两个任意的字符。一共有 n 种可能的变异。变异 ai->bici 表示字符 ai 有可能变异为两个字符 bici。详细来说,就是删掉一个字符 ai,之后在原来 ai 的位置处,插入 bi, ci 两个字符(注意字符 bi 必须在 ci 的前面)。每种变异都有可能发生任意多次。可以发现,每变异一次, DNA 串的长度会加 1。
如果有一种生物 a,他的 DNA 串是 s1,另外存在一种生物 b,他的 DNA 串是 s2。如果 s2 可以通过若干次变异变为 s1,那么生物 b 就被叫做生物 a 的祖先。
现在,给定一种生物,他的 DNA 串是 s。请找出他的一个祖先,且这个祖先的 DNA 串尽量短。
【输入】
输入文件 ancestor.in,共 n+2 行。
第一行包含一个非空字符串 s。
第二行含有一个整数 n,表示所有可能的变异。
接下来 n 行,每行描述一种可能的变异,按照 ai->bici 的格式。
s, ai, bi, ci 仅包含小写英文字母。
请注意:一种变异可能出现多次。
【输出】
输出文件名为 ancestor.out。
输出只有一行, 一个整数,表示祖先 DNA 串的最短长度。
【输入样例1】
ababa
2
c->ba
c->cc
【输出样例1】
2
【输入样例2】
ababa
7
c->ba
c->cc
e->ab
z->ea
b->ba
d->dd
d->ab
【输出样例2】
1
【数据范围】
对于 30%的数据, s 的长度<=5, N <= 3;
对于 100%的数据, s 的长度<=50, N <= 50
【题解】
DP题。设f[l][r][t]
代表区间[l,r]是否可以变成一个字母t,那么初始状态为f[i][i][t]=[s[i]==t]
。枚举区间的长度和端点,对于一个区间,转移的时候枚举中间点和所有变异即可。
再设一个fuck[l][r]
代表[l,r]合并后的最短长度。根据上面的设置,当(exist)f[l][r][t]=true
时,fuck[l][r]=1
,否则枚举中间点,fuck[l][r]
为两边相加的最小值。
f1
【问题描述】
F1,中文全称为一级方程式锦标赛,是最高级的方程式赛车比赛,现在你作为一名选手参加了一场 F1 的比赛,比较特殊地,本次比赛是在一个 N 个点 M 条边的无向图上举行的。
起点是 S,终点是 T,每条边长度为 1 公里,赛车每行驶 1 公里耗油 1 个单位,途中共有 k 个加油站, 每经过加油站时,可以把油加满,但你的赛车设计顾问告诉你,油箱容量越大,赛车跑的就越慢。 为了追求最快的速度, 在能顺利到达终点, 不会中途没油的前提下,你希望最小化油箱的容量(注意,虽然油箱变小可能导致路径变长,但我们只关心最小化的油箱)。
【输入】
输入文件 f1.in。
第一行一个正整数 T 表示测试数据组数, 每组数据格式如下:
第一行三个整数, N,M,K,表示无向图的点数,边数,加油站数。
第二行 K 个正整数 i1,i2..ik 表示这些点上有加油站(可能重复,保证至少一个加油站在S 点)。
接下来 M 行,每行两个正整数 Bi,Ei 表示有一条连接(Bi,Ei)的双向边(可能有重边和自环)。
最后一行两个正整数 S,T 表示起点、终点。
【输出】
输出文件名为 f1.out。
对于每组数据, 如果没法到达终点,输出-1,否则输出最小化的油箱容量。
【输入样例】
2
6 6 3
1 3 6
1 2
2 3
4 2
5 6
4 5
3 4
1 6
7 10 3
1 3 4
1 2
4 2
7 5
4 5
7 1
2 5
7 2
3 7
3 2
5 1
4 6
【输出样例】
3
-1
【数据范围】
对于 30%的数据, N<=200,M<=2000。
对于 60%的数据, N<=1000,M<=10000。
对于 100%的数据, 1<=K,S,T<=N<=100000,1<=M<=150000,1<=T<=5。
【题解】
由于答案是单调的(如果一个油箱容量合法,那么所有比这个容量大的油箱都合法),那么二分答案把题目转化为判定性问题。从起点开始,设d[i]为某点的油箱的最大值,跑最短路即可。注意这里必须使用spfa:下面的图如果用dijkstra就会出问题
[T]
|
|
[.]
|
|
|
[S] --- [.] --- [.] --- [O]
ASCII艺术。。。如图S是起点T是终点O是加油站,那么当油箱容量为3的时候,需要在加油站中转一下,这样我们重复更新了拐弯处的点的油箱信息。而dijkstra,bfs等算法是不允许重复更新某个节点的,而spfa允许,所以需要使用spfa。关于SPFA他其实没死,只是我们遇到最短路优先考虑dij更好。
ps昨天的题我自己厚颜无耻地从某网站扒的就不放了