Codeforces Round #250 (Div. 2)

最近学了python,决定拿这套Chinese Round(vfk一伙人出的)练练手。太弱,只能拿div 2练,囧。

link

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写水题很爽!

转载于:https://www.cnblogs.com/wangck/p/4394343.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值