• 2022杭电多校3(总结+补题)


    总结

    又躺了一把多校,全程是队友在过题,我不仅没过题还提供了好多罚时,死磕的题目一直没磕出来。。。。

    题解

    1003 - Cyber Language

    水题,输入字符串之后直接把每个单词的第一个字母大写输出即可。

    代码:

    /*
     author:wuzx
     */
    
    #include
    #define ll long long
    #define int long long
    #define endl "\n"
    #define P pair<int,int>
    #define f first
    #define s second
    using namespace std;
    typedef unsigned long long ull;
    const int maxn=200010;
    const int inf=0x3f3f3f3f;
    const int mod=998244353;
    int t;
    int n,m,k;
    signed main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        cin>>t;
        cin.get();
        while(t--)
        {
            string ss;
            getline(cin,ss);
            int len=ss.length();
            for(int i=0;i<len;)
            {
                if(ss[i]!=' ')
                {
                    cout<<(char)toupper(ss[i]);
                    int j;
                    for(j=i;j<len;j++)
                        if(ss[j]==' ')
                            break;
                    i=j;
                }
                else
                    i++;
            }
            cout<<endl;
        }   
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    1009 - Package Delivery

    题意:

    n n n 个快递,每个快递有相应的到达时间 l i l_i li 与最迟取快递的时间 r i r_i ri ,小 Q Q Q 每次最多可以取 k k k 个快递,问最少去取多少次快递能把所有快递拿回来。

    做法:我们考虑当前未取的快递中 r r r 最小的一个,我们在 r r r 这天把快递取走一定不会使最终的结果变差,也就是说,每次我们在当前未取的快递中选一个 r r r 最小的快递,并在当天尽可能的取走尽量多的快递(取走的快递要标记), 迭代即可得到最少的取快递次数,这里我们使用优先队列维护,每次选定 r r r 之后都将到达时间小于等于 r r r 的快递的截止日期及快递编号丢进优先队列中,优先取截止时间小的。

    代码:

    /*
     author:wuzx
     */
    
    #include
    #define ll long long
    #define int long long
    #define endl "\n"
    #define P pair<int,int>
    #define f first
    #define s second
    using namespace std;
    typedef unsigned long long ull;
    const int maxn=200010;
    const int inf=0x3f3f3f3f;
    const int mod=998244353;
    int t;
    int n,m,k;
    #define tp3 tuple<int,int,int>
    signed main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        cin>>t;
        while(t--)
        {
            cin>>n>>k;
            priority_queue<P,vector<P>,greater<P> >q;
            vector<tp3> a;
            vector<tp3> b;
            for(int i=0;i<n;i++)
            {
                int x,y;
                cin>>x>>y;
                a.emplace_back(x,y,i);
                b.emplace_back(x,y,i);
            }
            sort(b.begin(),b.end());//用于丢进优先队列
            sort(a.begin(),a.end(),[&](tp3 aa,tp3 bb)//按r从小到大排序,用于迭代
            {
                if(get<1>(aa)==get<1>(bb))
                    return get<0>(aa)<get<0>(bb);
                return get<1>(aa) < get<1>(bb);
            });
            vector<int> vis(n,0);
            int j=0,ans=0;
            for(int i=0;i<n;i++)
            {
                int idx=get<2>(a[i]);
                if(!vis[idx])//找到r最小的未取快递
                {
                    vis[idx]=1;
                    int r=get<1>(a[i]);
                    while(j<n&&get<0>(b[j])<=r)//将l<=r的快递丢进优先队列
                    {
                        if(get<2>(b[j])==idx)
                        {
                            j++;
                            continue;
                        }
                        q.emplace(get<1>(b[j]),get<2>(b[j]));
                        j++;
                    }
                    int nb=1;
                    ans++;
                    while(!q.empty())//优先取截止时间小的
                    {
                        if(nb==k)/取满k个或队列空即退出
                            break;
                        P aa=q.top();
                        q.pop();
                        if(!vis[aa.s])
                        {
                            vis[aa.s]=1;
                            nb++;
                        }
                    }
                }
            }
            cout<<ans<<endl;
        }   
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    1011 - Taxi

    题意:

    n n n 个点,给出 n n n 个点的坐标 ( x i , y i ) (x_i,y_i) (xi,yi) w i w_i wi ,给出 q q q 个查询,每个查询给出一个点 ( x ’ , y ′ ) (x’,y') (x,y) ,求 v a l = m a x ( ∣ x ′ − x i ∣ + ∣ y ′ − y i ∣ , w i ) ( 1 ≤ i ≤ n ) val=max(|x'-x_i|+|y'-y_i|,w_i)(1\le i\le n) val=max(xxi+yyi,wi)(1in)

    做法:

    我们知道一个点与另一个点的曼哈顿距离 $= max(\left {(x+y)+(-x_i-y_i),(-x+y)+(x_i-y_i),(x-y)+(-x_i+y_i),(-x-y)+(x_i+y_i) \right } ) $

    因此我们只需要记录 n n n 个点中 ( − x i − y i ) , ( x i − y i ) , ( − x i + y i ) , ( x i + y i ) (-x_i-y_i),(x_i-y_i),(-x_i+y_i),(x_i+y_i) (xiyi),(xiyi),(xi+yi),(xi+yi) 的最大值就可以 O ( 1 ) O(1) O(1) 得到 ( x ’ , y ’ ) (x’,y’) (x,y) n n n 个点的最长曼哈顿距离。我们再考虑有 w w w 的情况,我们将 n n n 个点按照 w w w 值从小到大排序,并记录每个点后缀 ( − x i − y i ) , ( x i − y i ) , ( − x i + y i ) , ( x i + y i ) (-x_i-y_i),(x_i-y_i),(-x_i+y_i),(x_i+y_i) (xiyi),(xiyi),(xi+yi),(xi+yi) 的最大值,再使用二分找到最大的 v a l val val

    二分求出当前点到 m i d mid mid 的距离 d d d

    w m i d < d w_{mid}wmid<d ,说明从 m i d mid mid n n n 之间的城镇中答案至少为 w m i d w_{mid} wmid ,因此可将 l l l 更新为 m i d + 1 mid+1 mid+1

    w m i d > = d w_{mid}>=d wmid>=d ,说明从 m i d mid mid n n n 之间的城镇中答案至多为 w m i d w_{mid} wmid ,因此可将 r r r 更新为 m i d − 1 mid-1 mid1

    代码:

    /*
     author:wuzx
     */
    
    #include
    #define ll long long
    #define int long long
    #define endl "\n"
    #define P pair<int,int>
    #define f first
    #define s second
    using namespace std;
    typedef unsigned long long ull;
    const int maxn=200010;
    const int inf=0x3f3f3f3f;
    const int mod=998244353;
    int t;
    int n,m,k;
    signed main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        cin>>t;
        while(t--)
        {
            int q;
            cin>>n>>q;
            vector<vector<P> > a(4,vector<P>(n));
            for(int i=0;i<n;i++)
            {
                int x,y,w;
                cin>>x>>y>>w;
                a[0][i]=make_pair(w,-x-y);
                a[1][i]=make_pair(w,x-y);
                a[2][i]=make_pair(w,-x+y);
                a[3][i]=make_pair(w,x+y);
            }
            for(int i=0;i<4;i++)
                sort(a[i].begin(),a[i].end(),[&](P aa,P bb)//按w排序
                {
                    return aa.f<bb.f;
                });
            vector<vector<int>> ma(4,vector<int>(n+1,-inf));
            for(int i=0;i<4;i++)//预处理四个值的后缀最大值
                for(int j=n-1;j>=0;j--)
                    ma[i][j]=max(ma[i][j+1],a[i][j].s);
            while(q--)
            {
                int x,y;
                cin>>x>>y;
                vector<int> b(4);
                b[0]=x+y;
                b[1]=-x+y;
                b[2]=x-y;
                b[3]=-x-y;
                int ans=0;
                int l=0,r=n-1,mid,nb=0;
                while(l<=r)//二分
                {
                    mid=(l+r)/2;
                    int n1=-inf;
                    for(int j=0;j<4;j++)
                        n1=max(n1,ma[j][mid]+b[j]);
                    if(a[0][mid].f<n1)
                    {
                        l=mid+1;
                        nb=max(nb,a[0][mid].f);
                    }
                    else
                    {
                        r=mid-1;
                        nb=max(nb,n1);
                    }
                }
                ans=max(ans,nb);
                cout<<ans<<endl;
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
  • 相关阅读:
    centos 7安装podman(类似docker)
    晶体的负载电容到底怎么选择
    Java之Collention集合
    Springboot毕业设计毕设作品,农产品销售系统设计与实现
    Ubuntu之apt-get系列--安装JDK8--方法/教程
    基于蒙特卡洛的大规模电动汽车充电行为分析(Matlab代码实现)
    数据结构之美:如何优化内存和性能
    SSM-spring注解式缓存redis
    Tuxera NTFS2023破解版苹果电脑磁盘读写工具
    Taro进阶
  • 原文地址:https://blog.csdn.net/m0_51028279/article/details/126024133