zoukankan      html  css  js  c++  java
  • 2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02)

    B Bricks 计算几何乱搞

    题意:

    给你个立方体,问你能不能放进一个管道里面。

    题解:

    这是一道非常迷的题,其问题在于,你可以不正着放下去,你需要斜着放。此时你需要枚举你旋转的角度,来判断是否可行。至于枚举的范围和步长,看脸乱搞。

    代码:

    //#include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<fstream>
    using namespace std;
    
    long double x[3],y[2];
    
    const long double pi=acos(-1);
    
    long double a,b;
    long double d,e;
    
    const long double eps=1e-5;
    
    int main() {
        ifstream cin("bricks.in");
        ofstream cout("bricks.out");
        cin.sync_with_stdio(false);
        cin >> x[0] >> x[1] >> x[2] >> y[0] >> y[1];
        sort(x, x + 3);
        sort(y, y + 2);
        a = x[0], b = x[1];
        d = y[0], e = y[1];
        if (d - a > -eps && e - b > -eps) {
            cout << "YES" << endl;
            return 0;
        }
        long double dd = pi / (2 * (3e6));
        for (long double t = acos(e / b); t < asin(d / b) + dd; t += dd) {
            if (min((e - b * cos(t)) / sin(t), (d - b * sin(t)) / cos(t)) > a - eps) {
                cout << "YES" << endl;
                return 0;
            }
        }
        cout << "NO" << endl;
        return 0;
    }
    View Code

    E Evacuation Plan 最小费用流

    题意:

    题目好长好长好长。。。。。简单说就是,发生核战争了,人们要避难,给你每个建筑的坐标,给你每个避难所的坐标,每个建筑里面有若干人,从一个建筑到一个避难所的时间,是坐标的曼哈顿距离,现在要你使总时间花费最少。

    题解:

    就最小费用的模板题。最后在残余网络上寻找解即可。

    代码:

    //#include <iostream>
    #include<vector>
    #include<fstream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<string>
    #include<cmath>
    #define MAX_V 222
    #define INF 1008611
    using namespace std;
    struct edge {
    public:
        int to, cap, cost, rev;
        bool isRev;
    
        edge(int t, int c, int co, int re,bool ir) : to(t), cap(c), cost(co), rev(re),isRev(ir) { }
    
        edge() { }
    };
    int V=0;
    vector<edge> G[MAX_V];
    int dist[MAX_V];
    int prevv[MAX_V],preve[MAX_V];
    
    void add_edge(int from,int to,int cap,int cost) {
        G[from].push_back(edge(to,cap,cost,G[to].size(),0));
        G[to].push_back(edge(from,0,-cost,G[from].size()-1,1));
    }
    
    char cc;
    int min_cost_flow(int s,int t,int f) {
        int res = 0;
        while (f > 0) {
            fill(dist, dist + V, INF);
            dist[s] = 0;
            bool update = 1;
            while (update) {
                update = 0;
                for (int v = 0; v < V; v++) {
                    if (dist[v] == INF)continue;
                    for (int i = 0; i < G[v].size(); i++) {
                        edge &e = G[v][i];
                        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
                            //cout<<"*"<<endl;
                            dist[e.to] = dist[v] + e.cost;
                            prevv[e.to] = v;
                            preve[e.to] = i;
                            update = 1;
                        }
                    }
                }
            }
            if (dist[t] == INF)
                return -1;
    
            int d = f;
            for (int v = t; v != s; v = prevv[v])
                d = min(d, G[prevv[v]][preve[v]].cap);
            f -= d;
            res += d * dist[t];
            for (int v = t; v != s; v = prevv[v]) {
                edge &e = G[prevv[v]][preve[v]];
                e.cap -= d;
                G[v][e.rev].cap += d;
            }
        }
        return res;
    }
    
    int n,m;
    
    struct build {
    public:
        int x, y,c;
    
        build(int xx, int yy,int cc) : x(xx), y(yy), c(cc){ }
    
        build() { }
    
        int dis(build a){
            return abs(a.x-x)+abs(a.y-y)+1;
        }
    };
    
    typedef build shelter;
    
    build bu[MAX_V];
    shelter sh[MAX_V];
    
    int plan;
    int S=0;
    
    int main() {
        ifstream cin("evacuate.in");
        ofstream cout("evacuate.out");
        cin.sync_with_stdio(false);
        cin >> n >> m;
        for (int i = 0; i < n; i++) {
            cin >> bu[i].x >> bu[i].y >> bu[i].c;
            S += bu[i].c;
        }
        for (int i = 0; i < m; i++)
            cin >> sh[i].x >> sh[i].y >> sh[i].c;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                int k;
                cin >> k;
                plan += k * bu[i].dis(sh[j]);
            }
        for (int i = 0; i < n; i++)
            add_edge(n + m, i, bu[i].c, 0);
        for (int j = 0; j < m; j++)
            add_edge(j + n, n + m + 1, sh[j].c, 0);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                add_edge(i, j + n, INF, bu[i].dis(sh[j]));
        V = n + m + 2;
        int tmp = min_cost_flow(n + m, n + m + 1, S);
        if (tmp == plan) {
            cout << "OPTIMAL" << endl;
            return 0;
        }
        cout << "SUBOPTIMAL" << endl;
        for (int i = 0; i < n; i++, cout << endl)
            for (int j = 0; j < G[i].size(); j++)
                if (!G[i][j].isRev)
                    cout << INF - G[i][j].cap << " ";
    
        return 0;
    }
    View Code

    I Inlay Cutters 模拟+图论

    题意:

    给你一个棋盘,现在切若干刀,问你最后有几个三角形。

    题解:

    由于三个点在平面上只能构成三角形,那么此题可以转化为图论问题来解决,将相邻的直线交点连边,然后在图上求有多少个三元环即可。

    代码:

    //#include<iostream>
    #include<fstream>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<cstdio>
    #include<string>
    #include<cmath>
    #define MAX_N 10004
    using namespace std;
    
    int N,M,K;
    
    int d[4];
    
    struct knife {
    public:
        int from, to, dir;
    
        knife(int f, int t, int d) : from(f), to(t), dir(d) { }
    
        knife() { }
    };
    
    knife kn[MAX_N];
    
    int cnt[MAX_N];
    
    vector<int> G[MAX_N];
    
    int main() {
        ifstream cin("inlay.in");
        ofstream cout("inlay.out");
        cin.sync_with_stdio(false);
        cin >> M >> N >> K;
        d[0] = 2 * M + 1;
        d[1] = 1;
        d[2] = M + 1;
        d[3] = M;
        for (int i = 0; i < K; i++) {
            int x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            if (y1 > y2 || (y1 == y2 && x1 > x2)) {
                swap(x1, x2);
                swap(y1, y2);
            }
            int u = x1 * d[1] + y1 * d[0];
            int v = x2 * d[1] + y2 * d[0];
            int t;
            if (x1 == x2)t = 0;
            else if (y1 == y2)t = 1;
            else if (x2 > x1)t = 2;
            else t = 3;
            kn[i] = knife(u, v, t);
        }
        kn[K++] = knife(0, M, 1);
        kn[K++] = knife(N * d[0], N * d[0] + M * d[1], 1);
        kn[K++] = knife(0, N * d[0], 0);
        kn[K++] = knife(M, N * d[0] + M, 0);
        for (int i = 0; i < K; i++) {
            int u = kn[i].from, v = kn[i].to, t = kn[i].dir;
            while (u != v) {
                cnt[u]++;
                u += d[t];
            }
            cnt[v]++;
        }
        int V = -1;
        for (int i = 0; i < K; i++) {
            int u = kn[i].from, v = kn[i].to, t = kn[i].dir;
            int p = u;
            while (u != v) {
                u += d[t];
                if (cnt[u] > 1) {
                    V = max(V, u);
                    V = max(V, p);
                    G[p].push_back(u);
                    G[u].push_back(p);
                    p = u;
                }
            }
        }
        int ans = 0;
        V++;
        for (int u = 0; u < V; u++)
            sort(G[u].begin(), G[u].end());
        for (int u = 0; u < V; u++)
            for (auto v:G[u])
                for (auto c:G[v]) {
                    if (c == u)continue;
                    int t = lower_bound(G[c].begin(), G[c].end(), u) - G[c].begin();
                    if (G[c][t] == u)ans++;
                    //cout<<c<<" "<<u<<" "<<v<<endl;
                }
        cout << ans/6 << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    docker学习之network:初识网络配置
    原来:HTTP可以复用TCP连接
    git tag的用法及意义
    Android,社招,面淘宝,指南【内部人员为你保驾护航】
    别了,拼多多!再也不想砍一刀了,哔哩哔哩 (゜-゜)つロ 干杯~
    【Android面试宝典】2021年,腾讯等大厂Android高级开发面试完全攻略!
    腾讯40岁老兵现身说法:35岁职业生涯分水岭,架构or管理,到底怎么选?
    【整理合集】Flutter 常用第三方库、插件、学习资料等
    [PAT]1011 World Cup Betting (20 分)Java
    [PAT] 1010 Radix (25 分)Java
  • 原文地址:https://www.cnblogs.com/HarryGuo2012/p/4782582.html
Copyright © 2011-2022 走看看