1 绕橡皮
(rope.cpp)
1.1 题目描述
最近小D喜欢玩橡皮筋。他发现用一个橡皮筋绕上一个正n边形的n个顶点可以产生许多美丽的形状。他发现用一个橡皮筋不重复也不遗漏地绕过n个顶点产生的图形中,有些图形不存在平行的边,称为“n奇异形“。现在他希望知道是否存在k个“n奇异形”叠置(即形成一个由正k*n边形的顶点及一些边组成的图形)之后形成的图形是否也满足不存在平行的边。
1.2 输入格式
有多组测试数据,每行包含两个正整数n,k,意义同上, 文件末尾为两个0。
1.3 输出格式
对于每组测试数据
输出1行
“Y” 表示存在一种叠置方案。
“N” 表示不存在“n奇异形”,或是不存在叠置方案
1.4 样例
样例1
Input:
3 3
0 0
Output
Y
样例2
Input:
3 2
0 0
Output:
N
样例3
Input:
4 3
0 0
Output:
N
1.5 样例解释
样例1中的存在如图叠置方案
样例2可以证明不存在叠置方案
样例3可以证明不存在4奇异形
1.6 数据约定
令T为数据组数。
10%的数据满足n,k <= 3, T = 1;
30%的数据满足n,k <= 10
50%的数据满足n,k <= 1000
100%的数据满足n,k <= 10^18, T <= 1000,n >= 3.
1.7 友情提示
送分题,不要想复杂了。
1 Rope
1.1 满分算法
k * m 为偶则输出N, 否则输出Y。
证明:
1.1.1不存在2*b奇异形
按顺序给顶点编号,令边i两顶点和为t[i],则t[i] mod n 相同的边为平行边。
则依题中构造方法“n奇异形”必有n条边。又因为无平行边,所以t[] mod n 构成mod n 的完全剩余系 即 {0,1,... ,n – 1}
所以应有0 +1+..+n – 1 + n * a= (1+..+n) * 2
则(n^2 + 3 * n) / 2 = a * n
有a = (n + 3) / 2;
又a为正整数,所以n不为偶。
1.1.2不存在k * n为偶的叠置方法。
与上类似
1.1.3存在k * n为奇的叠置方法。
证明:
我们只需证k个正n边形叠置必没有平行边(n * k为奇)即可。
令其中一边为(a, a + k) 若存在边(a + b, a + k - b) 其中bc * k(c为整数)。则不符合条件。
若存在该边,则
a + b + k = a + k – b 或
a + k + k – b = a + b 或
a + b + k – nk = a + k – b 或
a + k + k – b – nk = a + b
解得2 * b = 0(舍去) 或 b = k(舍去) 或 2 * b = n * k(舍去) 或 2 * (k - b) = n * k(舍去)
所以,命题得证。
2道路网络
(map.cpp)
2.1 题目描述
C国的道路网络由若干条双向线路组成。每条线路途经一些城市(可能会经过多次同一城市),位于线路上的两个城市a, b通过i号线路互相抵达的费用为w[i][a] + w[i][b]。现在有若干个询问,询问两城市互相到达的最小费用。
2.2 输入格式
第一行为城市数n与线路数m
以下m行每行描述一条线路:
第一个正整数l[i]为i号线路途经的城市数,接下来2 * l[i]个正整数,每两个数描述一个城市,依次表示途经的城市j,费用w[i][j];
接下来若干行每行两个正整数a,b表示询问a,b之间的最小费用,保证a b。
最后以0 0结束。
2.3输出格式
对于每组询问输出一行
若不存在路径输出 -1
否则输出最小费用
2.4样例
Input:
4 2
3 1 1 2 1 3 3
3 1 2 2 1 4 2
1 2
3 4
2 4
0 0
Output:
2
7
3
2.5样例解释
略。
2.6数据约定
令T为询问数
10%的数据满足n <= 10, m <= 3, T <= 3;
30%的数据满足n, T <= 100, m , l[i] <= 15;
50%的数据满足n <= 1000, T <= 100, m , l[i] <= 50;
100%的数据满足n <= 100000, m <= 300, T, l[i], w[i][j] <= 2000。
2 Map
2.1 10分算法
暴力即可。
2.2 30分算法
对于线路上每两个城市建边,再跑最短路或floyd。令e = m * l[i] ^ 2为边数复杂度O(Teloge ) 或 O(n ^ 3)。
2.3 50分算法
考虑对线路设点,则对线路中每个城市连一条边权为w[i][j]的边,再跑最短路。令e = m * l[i] 复杂度O(Teloge)。
2.4 满分算法
类似于上面的做法,我们发现线路数特别的少,所以我们仍对线路设点,将两条线路i,j所有交点的w[i][a] + w[j][a] 之和取最小值作为i, j的边,然后跑floyd即可,询问时将两点所在线路枚举取最小值即可。复杂度O(m^3 + m * l[i] + T * m^2)。
3下十万层!
(downstair.cpp)
3.1 题目描述
现在假设地下世界的侧面是一个N * N的平面。每隔一个单位高度放置了一个木板供你休息,但一旦踏上木板你就需要花费t[i]的时间离开,一开始你位于第一块木板。只要你能到达最下面的木板你就获胜了。但是距离你上方L + N - 1有一些针,他会以1个单位的速度下降,碰到它你就... 。而你水平方向的最大移动速度和下落速度也是1个单位。 同时当你在空中停留时间到达某个不吉利的时间c时,就会有妖怪将你.. (包含最后一刻落在木板上的情况)。假设木板对你没有阻碍作用,请问你到达底部木板在针落下之前最多还能欣赏多久的风景。
3.2 输入格式
第一行三个正整数N, L,c。
接下来N行
每行两个正整数 表示从上至下的第i个木板的位置x[i] 及耗时t[i];
3.3输出格式
若不能到达则输出 -1
否则输出一个正整数x,表示最长欣赏时间。
3.4样例
Input:
9 4 30
1 1
2 3
4 9
4 7
4 1
6 6
7 7
8 2
9 7
Out:
9
3.5样例解释
略。
3.6数据约定
对于10%的数据满足N <= 10;
对于30%的数据N,c <= 10000;
另外10%的数据保证c = N - 1;
对于60%的数据N , c<= 50000;
对于100%的数据N,c <= 200000, l < 10^9, t[i] < 10^4 x[i]单调不减,且max(x[i]) <= N;
3 downstair
3.1 10分算法
暴力枚举排列咯。
3.2 30分算法
看懂了题,Dp应该很容易想了吧。转移方程
朴素做法复杂度O(nc)。
3.3 满分算法
Dp中直接用平衡树维护即可,因为x[i] <= 10^5 线段树也可以,时间卡得比较紧。