最近学了python
,决定拿这套Chinese Round
(vfk一伙人出的)练练手。太弱,只能拿div 2
练,囧。
A - The Child and Homework
很有中国特色的一题。
算法
考你会不会编程。
代码
a = sorted([(len(input()) - 2, i) for i in 'ABCD'])
p = 0
if a[0][0] * 2 <= a[1][0]:
p += 1
if a[-2][0] * 2 <= a[-1][0]:
p += 2
print(['C', a[0][1], a[-1][1], 'C'][p])
B - The Child and Set
算法
贪心即可。
代码
target, limit = map(int, input().split())
def lowbit(x):
return x & (x ^ (x - 1))
ans = []
for i in range(limit, 0, -1):
x = lowbit(i)
if x <= target:
ans.append(i)
target -= x
if target:
print(-1)
else:
print(len(ans))
print(" ".join(map(str, ans)))
C - The Child and Toy
算法
贪心即可。
我们可以从消去边的角度来看。那么消去一条边((u,v))的代价是(cost[u])或(cost[v]),我们肯定选最少的那个。这样我们便给每条边定了一个方向,变成了有向图。
如果这个图是DAG
那么我们就能全部消去了,且花费一定是最少的。但如果有环就不行了。事实上是没有环的,如果有环a->b->c->...->a
,就会出现(x < y, y < z, z < x)这种不科学的事情。
代码
read = lambda: map(int, input().split())
n, m = read()
cost = list(read())
ans = 0
for i in range(m):
v, u = read()
ans += min(cost[v - 1], cost[u - 1])
print(ans)
D - The Child and Zoo
算法
考虑某个点作为多少个路径的最小点。
然后最小生成树统计即可。
代码
read = lambda: map(int, input().split())
n, m = read()
v = list(read())
e = []
for i in range(m):
x, y = map(lambda x: int(x) - 1, input().split())
e.append((x, y, min(v[x], v[y])))
e.sort(key = lambda x: x[2], reverse = True)
belong = list(range(n))
union = [[i] for i in belong]
size = [1] * n
ans = 0
for i, j, k in e:
fi, fj = belong[i], belong[j];
if fi == fj: continue
if not (len(union[fi]) > len(union[fj])):
fi, fj = fj, fi
ans += k * size[fi] * size[fj]
size[fi] += size[fj]
union[fi] += union[fj]
for t in union[fj]: belong[t] = fi
print("%.7lf" % (ans * 2 / n / (n - 1)))
E - The Child and Polygon
算法
直接DP就好。
这题python
过不了,而且除了我没有人用python
写,囧。
我服了python
,(O(8000000))的算法,(2s)都TLE
。
而且这题我还不会调试,用输出中间变量的方法弄了很久才过样例。QAQ
代码
class point:
def __init__(self, a, b):
self.x, self.y = a, b
def cross(a, b):
return a.x * b.y - a.y * b.x
def rePoint(a, b):
return point(a.x - b.x, a.y - b.y)
n = int(input())
a = []
for i in range(n):
x, y = map(int, input().split())
a.append(point(x, y))
a.append(a[0])
area = 0
for i in range(n):
area += cross(a[i], a[i + 1])
if area < 0:
a = a[::-1]
mod = 10**9 + 7
#dp = [[0] * n] * n 不要用这个,什么浅复制,坑人啊
dp = [[0] * n for i in range(n)]
for l in range(1, n):
for i in range(n):
j = i + l
if j >= n: break
if l == 1:
dp[i][j] = 1;
continue
else:
for k in range(i + 1, j):
if cross(rePoint(a[i], a[j]), rePoint(a[k], a[j])) > 0:
dp[i][j] += dp[i][k] * dp[k][j]
dp[i][j] %= mod
print(dp[0][-1])
以伟大的c++
代码结束这一题:
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long i64;
const int MAXN = 203;
const int MOD = (int) 1e9 + 7;
struct Point {
int x, y;
Point(int _x = 0, int _y = 0) :
x(_x), y(_y) {}
i64 operator * (const Point &o) const {
return (i64) x * o.y - (i64) y * o.x;
}
Point operator - (const Point &o) const {
return Point(x - o.x, y - o.y);
}
};
int n;
Point A[MAXN];
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i ++)
scanf("%d%d", &A[i].x, &A[i].y);
i64 area = 0;
A[n] = A[0];
for (int i = 0; i < n; i ++)
area += A[i] * A[i + 1];
if (area < 0) reverse(A, A + n);
static i64 dp[MAXN][MAXN];
for (int len = 1; len < n; len ++)
for (int i = 0; i < n; i ++) {
int j = i + len;
if (j >= n) break;
if (len == 1) {
dp[i][j] = 1;
continue;
}
for (int k = i + 1; k < j; k ++) {
if ((A[i] - A[j]) * (A[k] - A[j]) > 0) {
dp[i][j] += dp[i][k] * dp[k][j];
dp[i][j] %= MOD;
}
}
}
cout << dp[0][n - 1] << endl;
return 0;
}
总结
不是水题不要用python
!不是水题不要用python
!不是水题不要用python
!不是水题不要用python
!不是水题不要用python
!
python
写水题很爽!python
写水题很爽!python
写水题很爽!python
写水题很爽!python
写水题很爽!python
写水题很爽!