zoukankan      html  css  js  c++  java
  • 2019省赛再现

    C题:

    这道题卡了三个多小时,主要原因是特殊样例思考的不全面。最大距离除了可以在最后一次循环中取到以外,也可能在第一次循环中取到。例如所给的第一个样例,就是在最后一次循环取到最大值,此时我们只需要用循环一次以后距离的最终值*(k-1)+循环一次的最大值即可。如果是在第一次循环取到最大值,例如9,3,RRRRLLLLL,此时我们只需要输出第一次循环的最大值即可。把这两种情况综合起来的话就是先记录下第一次循环的最大值,然后进行n*k-1次循环(其中n*k-2次循环直接计算,不需要真正的循环,不然会超时),然后将最终结果和我们前面记录的第一次循环的最大值相比较,输出较大的那个就行。

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    #define ll long long

    int main()

    {

       int t,n,i,k,j;

       cin>>t;

       while(t--)

       {

           scanf("%d%d",&n,&k);

           string s;

           cin>>s;

           if(n==1)

           {

               cout<<k<<endl;

               continue;

           }

           ll u=0;

           ll r=0;

           ll mmax=0,ans,fin=0;

           ll first=0;

           for(i=0;i<n;i++)

           {

               if(s[i]=='U')

               {

                   u++;

               }

               else if(s[i]=='D')

               {

                   u--;

               }

               else if(s[i]=='R')

               {

                   r++;

               }

               else

               {

                   r--;

               }

               mmax=max(mmax,abs(u)+abs(r));

           }

           ll last1=u;

           ll last2=r;

           //cout<<"mmax="<<mmax<<endl;

            u*=(k-1);

            r*=(k-1);

           //fin=abs(u)+abs(r);

           //ans=(k-1)*fin+mmax;

           //first=mmax;

           //cout<<"final="<<fin<<endl;

           for(i=0;i<n;i++)

           {

                if(s[i]=='U')

               {

                   u++;

               }

               else if(s[i]=='D')

               {

                   u--;

               }

               else if(s[i]=='R')

               {

                   r++;

               }

               else

               {

                   r--;

               }

               mmax=max(mmax,abs(u)+abs(r));

           }

           cout<<mmax<<endl;

       }

       return 0;

    }

    D题:

    当时卡在了C题,这个题都没看。启示:卡在某一题,可以留两个人继续思考这个题,剩余一个人去看其他题。

    N个节点形成连通图就要至少有n-1要条边,一共有m条边,所以只需要取走m-n-1条边后,下一个取走边的人必输。但是可能会出现m-n-1比人数还多的情况,所以 要把m-n-1对人数去模,这时候看所给字符串中第(m-n-1)%p是什么,如果是1就是2队赢,反之就是1队赢。

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    int main()

    {

        int t,i,j,k;

        int n,m;

        cin>>t;

        while(t--)

        {

            int p;

            string s;

            cin>>p;

            cin>>s;

            cin>>n>>m;

            for(i=0;i<m;i++)

            {

                int a,b;

                cin>>a>>b;

            }

            int tem=n-1;

            int sheng=m-tem;

            sheng=sheng%p;

            if(s[sheng]=='1')

            {

                cout<<"2"<<endl;

            }

            else   

            {

                cout<<"1"<<endl;

            }

        }

        return 0;

    }

    H题:

    一波三折,最重要的是没学数据结构,不会用优先队列。首先是比赛的时候直接没看这道题,补题的时候先是用了数组标记,再用了结构体排序,结果一直wrong,看过题解才知道有一种情况:

    1

    3

    1 2

    2 2

    1 3

    在这个样例中由于在标记1 3时已经把2标记了,造成2 2无法被标记,使得答案错误。

    然后我改为采用先对右端点进行从小到大排序,再对左端点进行从小到大排序,虽然成功地解决了上述问题,却超时了。看过题解才知道,这道题是用优先队列来做,于是没学过数据结构的我只好现学优先队列的知识。启示:优先队列比结构体排序的效率更高?

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    #define ll long long

    struct node

    {

           int left,right;

    };

    bool operator<(node a,node b)

    {

           if(a.left==b.left)

           {

                  return a.right>b.right;

           }

           return a.left>b.left;

    }

    int main()

    {

           int t,n,i,j,k;

           cin>>t;

           priority_queue<node>q;

           struct node a;

           while(t--)

           {

                  cin>>n;

                  for(i=0;i<n;i++)

                  {

                         cin>>a.left>>a.right;

                         q.push(a);

                  }

                  int num=0,mmax=0;

                  while(!q.empty())

                  {

                         node b=q.top();

                         q.pop();

                         if(b.left>mmax)

                         {

                                num++;

                                mmax=b.left;

                         }

                         else

                         {

                                if(b.left<b.right)

                                {

                                       b.left++;

                                       q.push(b);

                                }

                         }

                  }

                  cout<<num<<endl;

           }

      return 0;

    }

  • 相关阅读:
    NGINX基本概念
    IP地址进制转换
    路由
    ip ,网段, 网关
    ipaddress模块
    第53课 被遗弃的多重继承(上)
    const static valitate 区别
    第49课 多态的概念和意义 (虚函数virtual)
    第75课 图的遍历(深度优先遍历DFS)
    第74课 图的遍历(广度优先遍历BFS)
  • 原文地址:https://www.cnblogs.com/chengxvzhishen/p/13767815.html
Copyright © 2011-2022 走看看