• Codeforces Round #575 (Div. 3)


      出题:A-B-D1-D2

      补题:C-E-F

      总结:B看错题,导致浪费非常多的时间,D2用前缀和分成三个写就超时,可能是我姿势不对。。。逃,心态炸了没读读懂C。。。还是太辣鸡了

      A. Three Piles of Candies

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    int main(){
      long long a,b,c;
      int n;
      while(~scanf("%d",&n)){
        while(n--){
         scanf("%lld%lld%lld",&a,&b,&c);
         printf("%lld
    ",(a+b+c)/2);
        }
      }
      return 0;
    }
    View Code

    B. Odd Sum Segments

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<vector>
    using namespace std;
    const int maxx = 2e5+6;
    int a[maxx];
    int main(){
      int t;
      int n,k;
      scanf("%d",&t);
      while(t--){
          vector<int>pos;
          scanf("%d%d",&n,&k);
          int cnt=0;
          for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if (a[i]%2==1){
                cnt++;
                pos.push_back(i);
            }
          }
          if (cnt<k || (cnt-k)%2==1){
            printf("NO
    ");
          }else {
            int s=1;
            printf("YES
    ");
            for (int i=1;i<pos.size();i++){
                    if (s==k)break;
                    printf("%d ",pos[i]-1);
                    s++;
            }
            printf("%d
    ",n);
          }
      }
      return 0;
    }
    View Code

    C. Robot Breakout

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<vector>
    using namespace std;
    int main(){
      int t,n;
      scanf("%d",&t);
      while(t--){
        scanf("%d",&n);
        int x,y;
        int max_x=1e5,max_y=1e5,min_x=-1e5,min_y=-1e5;
        int a,b,c,d;
        for (int i=1;i<=n;i++){
            scanf("%d%d",&x,&y);
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if (a==0){
                min_x=max(min_x,x);
            }
            if (b==0){
                max_y=min(max_y,y);
            }
            if (c==0){
                max_x=min(max_x,x);
            }
            if (d==0){
                min_y=max(min_y,y);
            }
        }
        if (max_x<min_x || max_y<min_y){
                printf("0
    ");
            }else {
                printf("1 %d %d
    ",max_x,max_y);
            }
        
      }
      return 0;
    }
    View Code

    D1. RGB Substring (easy version)

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int maxx = 2e5+6;
    char str[maxx];
    int main(){
      int t;
      scanf("%d",&t);
      int len,n;
      while(t--){
          scanf("%d%d",&n,&len);
          scanf("%s",str);
          int ans=0;
          for (int i=0;i<n-len+1;i++){
              int cnt=0;
              for (int j=1;j<=3;j++){
                  cnt=0;
                  if (j==1){
                     for (int k=0;k<len;k++){
                   //     cout<<i+k<<" ";
                        if (k%3==0 && str[i+k]=='B')cnt++;
                        if (k%3==1 && str[i+k]=='R')cnt++;
                        if (k%3==2 && str[i+k]=='G')cnt++;
                     }
                  }else if (j==2){
                    for (int k=0;k<len;k++){
                 //       cout<<i+k<<" ";
                        if (k%3==0 && str[i+k]=='R')cnt++;
                        if (k%3==1 && str[i+k]=='G')cnt++;
                        if (k%3==2 && str[i+k]=='B')cnt++;
                     }
                  }else {
                     for (int k=0;k<len;k++){
                 //       cout<<i+k<<" ";
                        if (k%3==0 && str[i+k]=='G')cnt++;
                        if (k%3==1 && str[i+k]=='B')cnt++;
                        if (k%3==2 && str[i+k]=='R')cnt++;
                     }
                  }
              //    cout<<endl;
                //  cout<<cnt<<endl;
                          ans=max(ans,cnt);
              }
          }
          printf("%d
    ",len-ans);
      }
      return 0;
    }
    View Code

    D2. RGB Substring (hard version)

    三种情况的三种不同前缀和,最后查询一遍即可

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int maxx = 2e5+6;
    char str[maxx];
    int pre[maxx][3];
    int main()
    {
        int t;
        scanf("%d",&t);
        int len,n;
        while(t--)
        {
            scanf("%d%d",&n,&len);
            scanf("%s",str+1);
            for (int i=1; i<=n; i++)
            {
                pre[i][0]=0;
                pre[i][1]=0;
                pre[i][2]=0;
            }
            int cnt1=0;
            int cnt2=0;
            int cnt3=0;
            for (int i=1; i<=n; i++)
            {
                if ((i-1)%3==0)
                {
                    if (str[i]=='R')cnt1++;
                    if (str[i]=='G')cnt2++;
                    if (str[i]=='B')cnt3++;
                    pre[i][0]=cnt1;
                    pre[i][1]=cnt2;
                    pre[i][2]=cnt3;
                }
                else if ((i-1)%3==1)
                {
                    if (str[i]=='G')cnt1++;
                    if (str[i]=='B')cnt2++;
                    if (str[i]=='R')cnt3++;
                    pre[i][0]=cnt1;
                    pre[i][1]=cnt2;
                    pre[i][2]=cnt3;
                }
                else
                {
                    if (str[i]=='B')cnt1++;
                    if (str[i]=='R')cnt2++;
                    if (str[i]=='G')cnt3++;
                    pre[i][0]=cnt1;
                    pre[i][1]=cnt2;
                    pre[i][2]=cnt3;
                }
            }
            int ans=0;
            for (int j=1; j<=n-len+1; j++)
            {
                int w=max(pre[j+len-1][0]-pre[j-1][0],max(pre[j+len-1][1]-pre[j-1][1],pre[j+len-1][2]-pre[j-1][2]));
                ans=max(ans,w);
            }
            printf("%d
    ",len-ans);
        }
        return 0;
    }
    View Code

    E. Connected Component on a Chessboard

    假如B<W,那么我们可以通过尽量构造1黑周围3个白,让差值减小2。不断减小

     当然如果差值为1的时候,我们可以通过构造1黑周围2个白,差值减小1,然后使得B和W的个数相同

     这个时候,直接B和W之间相邻构造就行了。

     然后把坐标保存下来,如果B>W个数,我们仍然按照上述构造,然后全部横坐标+1即可。

     也就是说,我们构造一条竖线,一定是黑白相间的,我们在竖线周围加上黑或者白多的那个,这样构造出来。

     动笔画画图就出来了。。。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define pii pair<int,int>
    #define mp make_pair
    using namespace std;
    vector<pii> ans;
    int main()
    {
        int t,b,w;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&b,&w);
            int three=0,two=0,one=0;
            ans.clear();
            int flag=0;
            if (b>w)
            {
                flag=1;
                swap(b,w);
            }
            if (3*b+1<w)
            {
                printf("NO
    ");
            }
            else
            {
                printf("YES
    ");
                int s_x=2,s_y=3;
                while(w>=1 && b>=1)
                {
                    if (w-b>=2)
                    {
                        ans.push_back(mp(s_x,s_y));
                        ans.push_back(mp(s_x+1,s_y));
                        ans.push_back(mp(s_x-1,s_y));
                        ans.push_back(mp(s_x,s_y+1));
                        w-=3;
                        b-=1;
                        s_y+=2;
                    }
                    else if (w-b>=1)
                    {
                        ans.push_back(mp(s_x,s_y));
                        ans.push_back(mp(s_x,s_y+1));
                        ans.push_back(mp(s_x+1,s_y));
                        w-=2;
                        b-=1;
                        s_y+=2;
                    }
                    else
                    {
                        ans.push_back(mp(s_x,s_y));
                        ans.push_back(mp(s_x,s_y+1));
                        w-=1;
                        b-=1;
                        s_y+=2;
                    }
                }
                if (w==1)
                {
                    ans.push_back(mp(2,2));
                }
                if (flag)
                {
                    for (int i=0; i<ans.size(); i++)
                    {
                        printf("%d %d
    ",ans[i].first,ans[i].second+1);
                    }
                }
                else
                {
                    for (int i=0; i<ans.size(); i++)
                    {
                        printf("%d %d
    ",ans[i].first,ans[i].second);
                    }
                }
            }
        }
        return 0;
    }
    View Code

    F. K-th Path

    这个题是个好题啊,点赞,题目就说是,给一些点,以及一些边,我们需要找出这些点集之间的第K短的路。

    。。。拿到就没什么想法,暴力弗洛伊德在1e5数据的下面,显然不现实,也没啥好的想法。。。

    后面大佬代码,看到一位大佬非常优秀的代码。

    考虑这样一个东西K,K实在太小了,小到只有400,那么其实你可以想到,我们的最坏情况,就是把边排序后的第400条边。

    我们把这K条边重新建图,那么这图就小的可怜了。。。

    点集不超过200,那么nlogn的最短路也就绰绰有余了。

    跑完最短路后,枚举点之间距离,放入小根堆,最后丢掉前K-1个即可

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #define pii pair<int,int>
    #define pli pair<long long,int>
    #define mp make_pair
    #define LL long long
    using namespace std;
    const int maxx = 2e5+6;
    const LL INF = 1e18;
    struct node{
      int x,y,w;
    }a[maxx];
    int order[maxx];
    struct Edge{
      int v,w,n;
    }edge[maxx];
    bool cmp(node a,node b){
       return a.w<b.w;
    }
    int tot;
    int head[maxx];
    LL dis[maxx];
    bool vis[maxx];
    void add(int x,int y,int z){
       edge[++tot]=(Edge){y,z,head[x]};
       head[x]=tot;
    }
    void dij(int s){
       priority_queue<pli>q;
       for (int i=1;i<=2e5+4;i++){
           dis[i]=INF;
       }
       memset(vis,0,sizeof(vis));
       q.push(mp(0,s));
       dis[s]=0;
       int x,y;
       while(q.size()){
             x=q.top().second;
             q.pop();
             if (vis[x])continue;
             vis[x]=1;
          for (int i=head[x];i;i=edge[i].n){
             y=edge[i].v;
             if (dis[y]>dis[x]+edge[i].w){
                 dis[y]=dis[x]+edge[i].w;
                 q.push(mp(-dis[y],y));
             }
          }
       }
    }
    int main(){
      int n,m,k;
      while(~scanf("%d%d%d",&n,&m,&k)){
          tot=1;
          memset(head,0,sizeof(head));
          memset(vis,0,sizeof(vis));
          memset(edge,0,sizeof(edge));
          for (int i=1;i<=m;i++){
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
          }
          sort(a+1,a+1+m,cmp);
          int cnt=0;
          for (int i=1;i<=min(k,m);i++){
              add(a[i].x,a[i].y,a[i].w);
              add(a[i].y,a[i].x,a[i].w);
              if (!vis[a[i].x])vis[a[i].x]=1,order[++cnt]=a[i].x;
              if (!vis[a[i].y])vis[a[i].y]=1,order[++cnt]=a[i].y;
          }
          priority_queue<LL>ans;
          while(ans.size())ans.pop();
          for (int i=1;i<=cnt;i++){
              dij(order[i]);
              for (int j=i+1;j<=cnt;j++){
                 ans.push(-dis[order[j]]);
              }
          }
          for (int i=1;i<k;i++){
            ans.pop();
          }
          printf("%lld
    ",-ans.top());
      }
      return 0;
    }
    View Code
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    蛙蛙推荐:蛙蛙牌正文提取算法
    javascript太牛了,还能模拟函数式编程
    蛙蛙推荐:编写一个服务监控及管理的软件
    蛙蛙推荐:Remoting超时问题及初步解决方案
    WaTu项目简介
    蛙蛙推荐:基于标记窗的网页正文提取算法的一些细节问题
    【蛙蛙推荐】windbg使用小总结
    蛙蛙推荐:windbg里查看DateTime值
    Enterprise Library :数据访问程序块学习1 dodo
    (转)一个带自定义分页,排序功能的DATAGRID控件(公开源码) dodo
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11247591.html
Copyright © 2020-2023  润新知