zoukankan      html  css  js  c++  java
  • ABC224

    C

    题意:给你一堆不同的点,从中选三个点,能够获得的三角形个数有多少

    方法:选三个点,判断是否三点共线,或者用海伦公式判断面积是否为0

    #include<iostream>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    #define int long long
    
    vector<pair<int, int>> v;
    int n;
    
    signed main(){
        cin >> n;
        for(int i = 0; i < n; i ++){
            int a, b;
            cin >> a >> b;
            v.push_back({a, b});
        }
        
        int res = 0;
        for(int i = 0; i < n; i ++)
            for(int j = i + 1; j < n; j ++)
                for(int k = j + 1; k < n; k ++){
                    int dx0 = v[j].first - v[i].first;
                    int dy0 = v[j].second - v[i].second;
                    int dx1 = v[k].first - v[j].first;
                    int dy1 = v[k].second - v[j].second;
                    
                    if(dx0 * dy1 != dy0 * dx1) res ++;
                }
                        
        cout << res << endl;
        return 0;
    }
    

    D

    题意:无向图上的八数码问题

    #include<iostream>
    #include<string>
    #include<vector>
    #include<unordered_map>
    #include<queue>
    
    using namespace std;
    
    #define int long long
    
    unordered_map<string, int> st;
    
    int m;
    vector<int> h[10];
    queue<string> q;
    
    signed main(){
        cin >> m;
        while(m --){
            int a, b;
            cin >> a >> b;
            a --, b --;
            h[a].push_back(b);
            h[b].push_back(a);
        }
        
        string s(9, '0');
        for(int i = 1; i <= 8; i ++){
            int a;
            cin >> a;
            a --;
            s[a] = '0' + i;
        }
        
        q.push(s);
        st[s] = 1;
        
        if(s == "123456780"){
            puts("0");
            return 0;
        }
        
        while(q.size()){
            auto s = q.front();
            q.pop();
            
            int e = s.find('0');
            
            for(int i = 0; i < h[e].size(); i ++){
                int j = h[e][i];
                
                string ns = s;
                swap(ns[j], ns[e]);
                
                if(st[ns]) continue;
                
                st[ns] = st[s] + 1;
                q.push(ns);
                
                if(ns == "123456780"){
                    cout << st[ns] - 1 << endl;
                    return 0;
                }
            }
        }
        
        cout << -1 << endl;
    }
    

    E

    题意:给你一个网格g,g中有N个点上写了数字,第i个点可以向第j个点走需要满足

    1. (r_i = r_jor c_i = c_j)
    2. (A_i < A_j)

    输出从每一个点出发,最多能走的步数

    方法:dp

    状态:(f(i))表示从第i个点出发能走的最多步数

    状态计算:(f(i) = max(f(j) + 1),(r_i = r_jor c_i = c_j)and A_i < A_j)

    初始条件:f[1~n] = 0

    可以用记忆化,如果用dp,就需要先根据a值升序排序,并且还需要保存每个点的位置,然后倒着转移,此时复杂度为(O(n^2)),N最大为1e5过不了

    优化:将所有的点按照a值分成几批,然后根据a值从大到小进行状态转移,维护cmax和rmax,cmax[c]和rmax[r]分别表示第c列上能够转移的最大步数,和第r行上能够转移的最大步数(因为是按照a值从大到小做的,所以如果第r行上有值,就一定是可以转移到的),此时状态转移为(f(i) = max{cmax[point[i].c], rmax(point[i].r))})

    并且每一次更新完f(i)还需要更新

    [cmax[point[i].c] = max{cmax[point[i].c], f(i) + 1}\ rmax[point[i].r] = max{rmax[point[i].r], f(i) + 1} ]

    #include<iostream>
    #include<map>
    #include<vector>
    
    using namespace std;
    
    int h, w, n;
    
    const int N = 2e5 + 10;
    
    struct node{
        int r, c;
        int i;
    };
    
    map<int, vector<node>> m;
    
    int rmax[N], cmax[N];
    int f[N];
    
    int main(){
        cin >> h >> w >> n;
        for(int i = 1; i <= n; i ++){
            int r, c, a;
            cin >> r >> c >> a;
            m[a].push_back({r, c, i});
        }
        
        for(auto it = m.rbegin(); it != m.rend(); it ++){
            for(auto t : it->second) f[t.i] = max(cmax[t.c], rmax[t.r]);
            for(auto t : it->second){
                cmax[t.c] = max(cmax[t.c], f[t.i] + 1);
                rmax[t.r] = max(rmax[t.r], f[t.i] + 1);
            }
        }
        
        for(int i = 1; i <= n; i ++) cout << f[i] << endl;
    }
    
  • 相关阅读:
    bzoj-2748 2748: [HAOI2012]音量调节(dp)
    bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
    bzoj-3444 3444: 最后的晚餐(组合数学)
    codeforces 709E E. Centroids(树形dp)
    codeforces 709D D. Recover the String(构造)
    codeforces 709C C. Letters Cyclic Shift(贪心)
    codeforces 709B B. Checkpoints(水题)
    codeforces 709A A. Juicer(水题)
    Repeat Number
    hdu 1003 Max Sum (动态规划)
  • 原文地址:https://www.cnblogs.com/tomori/p/15450515.html
Copyright © 2011-2022 走看看