zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ",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;
        }
    }
  • 相关阅读:
    二叉树专题
    强化学习的几个基本概念
    LeetCode #111 二叉树的最小深度
    NC127 最长公共子串
    快速排序
    NC78 反转链表
    《合作的进化》读后总结
    Optional和Stream的map与flatMap
    最爱的小工具,谁用谁知道!
    SpringBoot应用启动过程分析
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6933588.html
Copyright © 2011-2022 走看看