• 2019山东省赛重现补题总结


    题外话

    赛后做了一下队友做的H和没做出来的L
    感觉其实还挺简单, 就是没往那边去想,亦或者说,对这个算法掌握的不熟练。

    H 题目链接

    题意

    给你几个线段, 然后你可以在每个线段上找一个点(这个点必须是在y轴方向上, 没有别的点和它平行,就是一竖行上只能有一个点),然后问你有这个点的线段(这个线段至少有一个点,多个也没问题)有多少

    思路

    一看给的是一条线段的左右端点, 肯定考虑对左端点排序,再对右端点排序

    • 这个题,因为可能会给你在x点相同,y点不同的几条线段(例子: 1 2 1 2 1 2(他y根据题目上说是i,就是从i =1 开始) 就是 (1,1)(2,1) (1 , 2) (2 , 2) (1,3 )(2, 3)),所以我们需要判断当前点移动的位置上,y轴有没有被占用,
      • 没有就使用
      • 有的话,就移动当前点(只要当前点x 还小于当前的y就行)++ , 发现超过这条线段的右端点, 那么就跳到另外一条线段上
    • 通过上面的分析, 我们只需要用一个优先队列并对 < 进行重载就行了

    代码

    #include <cstdio>
    #include <algorithm>
    #include<iomanip>
    #include <iostream>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <cstring>
    #include<stack>
    #include <cassert>
    #include<map>
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    #define pn printf("
    ");
    #define pk printf(" ");
    #define p(n) printf("%d",n);
    #define pln(n) printf("%d
    ",n);
    #define s(n) scanf("%d",&n);
    #define ss(n) scanf("%s",n);
    #define ps(n) printf("%s",n);
    #define sld(n) scanf("%lld",&n);
    #define pld(n) printf("%lld",n);
    #define slf(n) scanf("%lf",&n);
    #define plf(n) printf("%lf",n);
    #define sc(n) scanf("%c",&n);
    #define pc(n) printf("%c",n);
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)
    
    using namespace std;
    //using namespace __gnu_pbds;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const LL Max = 9.1e10;
    const int N =3.1e5;
    const int maxn = 200010;
    
    void clear(unsigned char *pta, int size )
    {//结构体初始化
        while(size>0)
        {
            *pta++ = 0;
            size --;
        }
    }
    
    LL   n, k, m ;
    LL ar[N],br[N];
    LL i,j,g;
    LL MOD = 998244353 ;
    struct node {
        int l ,r ;
        bool operator < (const node & x)const {
            if(l==x.l)return r > x.r;
            return l>x.l;
        }
    
    };
    
    priority_queue<node > q;
    
    void answer(){
        cin >>n ;
    
        for(int i=1 ;i<=n;i++){
            node  no;
            cin >>no.l>>no.r;
            q.push(no);
        }
        LL cnt =0  , h = 0;
        while(!q.empty()){
            node New = q.top();
            q.pop();
            if(New.l>h){
                cnt ++ ;
                h = New.l;
            }
            else if(New.l < New.r){
                New.l++ ;
                q.push(New);
            }
        }
        cout<<cnt<<endl;
    
       return ;
     }
    
    
    int main()
    {
    //    ios::sync_with_stdio(0);
    //    cin.tie(0), cout.tie(0);
    //       pre();
        LL t;sld(t);
        while(t--)
            answer();
    
    
        return 0;
    
    }
    
    

    L 题目链接

    题意

    给你几个点,然后告诉你这些点左边严格大于右边,问你 有几个点可以成为中间的点

    思路

    因为条件是大于的关系, 所以可以把这个看成一个有向图(左边的点指向右边的点)

    • 这样我们只需要考虑什么情况下,这个有向图能够有点在中间呢?
      • 首先,我们根据离散的知识(数据结构也行)知道,有自环的有向图肯定是不能成立的(要么这个图不能联通, 要么这个图成为环)
      • 然后, 我们此时只需要考虑什么能求闭包问题的算法 ,发现floyed算法, 但是因为它的复杂度太高,再看看数据,发现数据范围还行,那就直接上手!
    • 在找到算法和思路后, 只需要最后判断一下, 每个点的出度和入度是否是大于等于(等于是因为题面说 n 一定是个奇数)(n+1)/2即可

    代码

    #include <cstdio>
    #include <algorithm>
    #include<iomanip>
    #include <iostream>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <cstring>
    #include<stack>
    #include <cassert>
    #include<map>
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    #define pn printf("
    ");
    #define pk printf(" ");
    #define p(n) printf("%d",n);
    #define pln(n) printf("%d
    ",n);
    #define s(n) scanf("%d",&n);
    #define ss(n) scanf("%s",n);
    #define ps(n) printf("%s",n);
    #define sld(n) scanf("%lld",&n);
    #define pld(n) printf("%lld",n);
    #define slf(n) scanf("%lf",&n);
    #define plf(n) printf("%lf",n);
    #define sc(n) scanf("%c",&n);
    #define pc(n) printf("%c",n);
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)
    
    using namespace std;
    //using namespace __gnu_pbds;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const LL Max = 9.1e10;
    const int N =3.1e5;
    const int maxn = 200010;
    
    void clear(unsigned char *pta, int size )
    {//结构体初始化
        while(size>0)
        {
            *pta++ = 0;
            size --;
        }
    }
    
    LL   n, k, m ;
    LL ar[N],br[N];
    LL i,j,g;
    LL MOD = 998244353 ;
    
    LL floyed[110][110];
    LL in[maxn],out[maxn];
    
    
    
    LL fac[N],inv_fac[N];
    //快速幂
    LL qpow(LL x, LL y ){
        x%=MOD;
        long long res=1%MOD;
        while(y){
            if(y&1)res=res*x%MOD;
            y>>=1;
            x=x*x%MOD;
        }
        return res;
    
    }
    
    void pre(){
        fac[0] =1 ;
        for(int i=1;i<N;i++){
            fac[i] =fac[i-1] * i %MOD;
        }
        inv_fac[N - 1 ] = qpow(fac[N - 1] , MOD-2 ) ;
    
        for(int i =N-2 ;i>=0 ;i--){
            inv_fac[i] = inv_fac[i+1] * (i+1) %MOD;
        }
    
    }
    
    LL C (LL a ,LL b){
        if(a<0 || b> a )//因为是C(a,b) 所以b《= a
        {
            return 0;
        }
    
        return fac[a] * inv_fac[b] % MOD *inv_fac[a-b]%MOD;//a 的阶乘 / ( b的阶乘 * (a-b的阶乘))
    
    }
    
    void answer(){
        sld(n); sld(m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                floyed[i][j] =0 ;
            }
        }
        for(int i=1;i<=m;i++){
            int x, y ;s(x);s(y);
            floyed[x][y] =1 ;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int g=1;g<=n;g++){
                    floyed[j][g] |= floyed[j][i]&floyed[i][g];
                }
            }
        }
        cl(in),cl(out);int flag = 0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(floyed[i][j]){
                    if(i == j){
                        flag = 1 ;
                        break;
                    }
                    in[j]++;
                    out[i] ++;
                }
    
            }
            if(flag)break;
        }
        if(flag){
            for(int i=1;i<=n;i++)p(0);pn;
            return ;
        }
    
        for(int i=1;i<=n;i++){
            if(in[i]>=((n+1)/2)||out[i]>=((n+1)/2)){
                p(0);
            }
            else {
                p(1);
            }
    
        }pn;
       return ;
     }
    
    
    int main()
    {
    //    ios::sync_with_stdio(0);
    //    cin.tie(0), cout.tie(0);
    //       pre();
        LL t;sld(t);
        while(t--)
            answer();
    
    
        return 0;
    
    }
    
    
  • 相关阅读:
    Android Studio的git功能的使用介绍
    如何用Android Studio同时使用SVN和Git管理项目
    【.NET深呼吸】动态类型(扩充篇)
    【.net深呼吸】动态类型(高级篇)
    【.net深呼吸】动态类型(娱乐篇)
    VS 2015相当不错的功能:C#交互窗口
    计算照片的面积(WPF篇)
    计算照片的面积(UWP篇)
    【Win 10应用开发】把文件嵌入到XML文档
    【.NET深呼吸】基础:自定义类型转换
  • 原文地址:https://www.cnblogs.com/gaohaoy/p/13752802.html
Copyright © 2020-2023  润新知