World final 2017 题解

链接:https://pan.baidu.com/s/1kVQc9d9

Problem A:

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

const int maxn = 222;

struct Point
{
    long long x, y;
    Point(long long x = 0, long long y = 0) : x(x), y(y) { }
    void read()
    {
        scanf("%lld %lld", &x, &y);
    }
};

typedef Point Vector;

Vector operator - (const Point &A, const Point &B)
{
    return Vector(A.x - B.x, A.y - B.y);
}

long long Cross(const Vector &A, const Vector &B)
{
    return A.x * B.y - A.y * B.x;
}

long long Dot(const Vector &A, const Vector &B)
{
    return A.x * B.x + A.y * B.y;
}

double inter(Point p, Vector v, Point q, Vector w)
{
    Vector u = p - q;
    return 1.0 * Cross(w, u) / Cross(v, w);
}

bool on(Point p, Point a, Point b)
{
    return Cross(p - a, p - b) == 0;
}

int dcmp(long long x)
{
    if (x == 0)
        return 0;
    return x > 0 ? 1 : -1;
}

int n;
Point p[maxn];
double ans = 0.0;

void solve(Point A, Point B)
{
    vector<double> lst;
    for (int i = 0; i < n; ++i)
    {
        if (dcmp(Cross(p[i] - A, B - A)) * dcmp(Cross(p[i + 1] - A, B - A)) >= 0)
            continue;
        lst.push_back(inter(A, B - A, p[i], p[i + 1] - p[i]));
    }
    for (int i = 0; i < n; ++i)
    {
        if (!on(p[i], A, B))
            continue;
        Point L = p[(i + n - 1) % n];
        Point N = p[(i + 1) % n];
        Point P = p[i];
        long long dir = Cross(B - A, L - A);
        double pos = 1.0 * Dot(P - A, B - A) / Dot(B - A, B - A);
        if (dir == 0)
        {
            if (Dot(B - A, P - L) > 0)
            {
                if (Cross(B - A, N - A) > 0)
                    lst.push_back(pos);
            }
            else
            {
                if (Cross(B - A, N - A) < 0)
                    lst.push_back(pos);
            }
        }
        else if (dir > 0)
        {
            if (Cross(B - A, N - A) < 0)
                lst.push_back(pos);
            else if (Cross(B - A, N - A) == 0 && Dot(B - A, N - P) > 0)
                lst.push_back(pos);
        }
        else
        {
            if (Cross(B - A, N - A) > 0)
                lst.push_back(pos);
            else if (Cross(B - A, N - A) == 0 && Dot(B - A, N - P) < 0)
                lst.push_back(pos);
        }
    }
    sort(lst.begin(), lst.end());
    double len = sqrt(Dot(B - A, B - A));
    for (int i = 0; i < (int)lst.size(); i += 2)
        ans = max(ans, (lst[i + 1] - lst[i]) * len);
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        p[i].read();
    p[n] = p[0];
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            solve(p[i], p[j]);
    printf("%.10f\n", ans);
    return 0;
}

Problem C:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 305, M = 100005;

const ll inf = 1ll << 60;

int head[N];

struct Edge {
    int nxt, to, cow;
    ll cost;
    Edge() {}
    Edge(int nxt, int to, int cow, ll cost) : nxt(nxt), to(to), cow(cow), cost(cost) {}
} ed[M];

int ecnt, mx_flow;

ll mi_cost;

void init() {
    mx_flow = mi_cost = ecnt = 0;
    memset(head, -1, sizeof(head));
}

void addE(int u, int v, int cow, ll cost) {
    ed[ecnt] = Edge(head[u], v, cow, cost);
    head[u] = ecnt ++;
    ed[ecnt] = Edge(head[v], u, 0, -cost);
    head[v] = ecnt ++;
}

queue <int> Q;

ll dis[N];

int pre[N], inq[N], tot;

bool spfa(int S, int T) {
    for (int i = 0; i < tot; ++ i)
        dis[i] = inf;
    dis[S] = 0;
    Q.push(S);
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        inq[u] = 0;
        for (int e = head[u]; ~e; e = ed[e].nxt) {
            if (!ed[e].cow)
                continue;
            int v = ed[e].to;
            if (dis[v] > dis[u] + ed[e].cost) {
                dis[v] = dis[u] + ed[e].cost;
                pre[v] = e;
                if (!inq[v]) {
                    inq[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
    return dis[T] < 0;
}

void aug(int S, int T) {
    int flow = 1 << 30;
    for (int u = T; u != S; u = ed[pre[u] ^ 1].to)
        flow = min(flow, ed[pre[u]].cow);
    for (int u = T; u != S; u = ed[pre[u] ^ 1].to) {
        ed[pre[u]].cow -= flow;
        ed[pre[u] ^ 1].cow += flow;
        mi_cost += flow * ed[pre[u]].cost;
    }
    mx_flow += flow;
}

int A[105][105];

int mxr[105], mxc[105];

int idr[105], idc[105];

int main() {
    init();
    int n, m;
    scanf("%d%d", &n, &m);
    long long sum = 0;
    for (int i = 0; i < n; ++ i)
        for (int j = 0; j < m; ++ j)
            scanf("%d", A[i] + j), sum += A[i][j];
    for (int i = 0; i < n; ++ i) {
        mxr[i] = - (1 << 30);
        for (int j = 0; j < m; ++ j)
            mxr[i] = max(mxr[i], A[i][j]);
    }
    for (int j = 0; j < m; ++ j) {
        mxc[j] = - (1 << 30);
        for (int i = 0; i < n; ++ i)
            mxc[j] = max(mxc[j], A[i][j]);
    }
    tot = 0;
    for (int i = 0; i <= n; ++ i)
        idr[i] = tot ++;
    for (int i = 0; i <= m; ++ i)
        idc[i] = tot ++;
    int src = tot ++, des = tot ++;
    int use = 0;
    for (int i = 0; i < n; ++ i)
        if (mxr[i])
            addE(src, idr[i], 1, - (1 << 30)), ++ use;
    for (int i = 0; i < m; ++ i)
        if (mxc[i])
            addE(idc[i], des, 1, - (1 << 30)), ++ use;
    addE(src, idr[n], 1 << 30, 0);
    addE(idc[m], des, 1 << 30, 0);
    long long ans = 0;
    for (int i = 0; i < n; ++ i) {
        for (int j = 0; j < m; ++ j) {
            if (A[i][j] == 0)
                continue;
            ++ ans;
            if (mxr[i] < mxc[j]) {
                addE(idr[i], idc[m], 1, mxr[i] - 1);
            } else if(mxr[i] > mxc[j]) {
                addE(idr[n], idc[j], 1, mxc[j] - 1);
            } else {
                addE(idr[i], idc[j], 1, mxr[i] - 1);
                addE(idr[i], idc[m], 1, mxr[i] - 1);
                addE(idr[n], idc[j], 1, mxr[i] - 1);
            }
        }
    }
    while(spfa(src, des))
        aug(src, des);
    mi_cost += (1ll << 30) * use;
    ans += mi_cost;
    cout << sum - ans << endl;
    return 0;
}

Problem E:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int n;
double t,d[maxn],s[maxn];
double check(double x){
    double res = 0;
    for(int i=0;i<n;i++){
        if(s[i]+x<=0){
            return 10000000.0;
        }
        res += d[i]/(s[i]+x);
    }
    return res;
}
int main(){
    cin>>n>>t;
    for(int i=0;i<n;i++)
        cin>>d[i]>>s[i];
    double l=-1e9,r=1e9;
    for(int cas=0;cas<=100;cas++){
        double mid = (l+r)/2.0;
        if(check(mid)>t)l=mid;
        else r=mid;
    }
    printf("%.12f\n",l);
}

Problem F:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 260;
long long d[maxn];
long long dp[maxn][maxn];
long long cal[maxn][maxn];
int n,m;
int a,b;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d%d",&a,&b);
        a++;
        d[a]+=b;
    }
    for(int i=0;i<maxn;i++){
        for(int j=2;j<maxn;j++){
            dp[i][j]=10000000000000000LL;
        }
    }
    for(int i=1;i<=256;i++){
        for(int j=i+1;j<=256;j++){
            for(int i2=i+1;i2<j;i2++){
                cal[i][j]+=1ll*min(i2-i,j-i2)*min(i2-i,j-i2)*d[i2];
            }
        }
    }
    for(int i=1;i<=256;i++){
        for(int j=1;j<i;j++){
            dp[i][1]+=1ll*(i-j)*(i-j)*d[j];
        }
    }
    for(int i=1;i<=256;i++){
        for(int j=1;j<=i;j++){
            for(int i2=2;i2<=m;i2++){
                dp[i][i2]=min(dp[i][i2],dp[j][i2-1]+cal[j][i]);
            }
        }
    }
    for(int i=1;i<=256;i++){
        for(int j=i+1;j<=256;j++){
            dp[i][m]+=1ll*(j-i)*(j-i)*d[j];
        }
    }
    long long Res = 10000000000000000LL;
    for(int i=1;i<=256;i++){
        Res = min(Res,dp[i][m]);
    }
    cout<<Res<<endl;
}

Problem I:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 30;
int mp[maxn][maxn];

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    string a,b;
    for(int i=0;i<n;i++){
        cin>>a>>b;
        mp[a[0]-'a'][b[0]-'a']=1;
    }
    for(int k=0;k<26;k++){
        mp[k][k]=1;
        for(int i=0;i<26;i++){
            for(int j=0;j<26;j++){
                if(mp[i][k]&&mp[k][j])
                    mp[i][j]=1;
            }
        }
    }
    string s1,s2;
    for(int i=1;i<=m;i++){
        cin>>s1>>s2;
        if(s1.size()!=s2.size()){
            cout<<"no"<<endl;
            continue;
        }
        int flag = 1;
        for(int j=0;j<s1.size();j++){
            if(mp[s1[j]-'a'][s2[j]-'a']==0)
                flag = 0;
        }
        if(flag == 0)
            cout<<"no"<<endl;
        else
            cout<<"yes"<<endl;
    }
}
posted @ 2017-06-02 15:31  qscqesze  阅读(1268)  评论(0编辑  收藏  举报