• UPC2018组队训练赛第八场


    题目来自NCPC2017


    B题:Best Relay Team

    直接按照题意做

     1 #include <bits/stdc++.h>
     2  
     3 using namespace std;
     4  
     5 struct node
     6 {
     7     string name;
     8     double n1;
     9     double n2;
    10 }a[505];
    11  
    12 bool cmp(node a,node b)
    13 {
    14     return a.n2<b.n2;
    15 }
    16  
    17 int main()
    18 {
    19     int n;
    20     cin>>n;
    21     for(int i=0;i<n;i++)
    22     {
    23         cin>>a[i].name>>a[i].n1>>a[i].n2;
    24     }
    25     sort(a,a+n,cmp);
    26     string ansnm = a[0].name;
    27     double ans = INT_MAX;
    28     for(int i=0;i<n;i++)
    29     {
    30         int cnt = 1;
    31         double now = a[i].n1;
    32         for(int j=0;j<n;j++)
    33         {
    34             if(j!=i)
    35             {
    36                 now += a[j].n2;
    37                 cnt++;
    38             }
    39             if(cnt==4)
    40             {
    41                 break;
    42             }
    43         }
    44  
    45         if(now<ans)
    46         {
    47             ansnm = a[i].name;
    48             ans = now;
    49         }
    50     }
    51     cout<<ans<<endl<<ansnm<<endl;
    52     return 0;
    53 }
    View Code

     

     

    E题:Emptying the Baltic

    有一张地图,地图上有每个区域的海拔高度,负数表示海平面以下,被水覆盖;正数表示海平面以上,没有水。在(x,y)的海底处安装一个抽水装置。水只能往低处流,或者流向抽水机。问抽水机能抽多少水

    用优先队列+bfs。bfs过程中,对于两个相邻的海底区域,每次取高度的最大值,放到优先队列(高度高的在前面)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int d[8][2]={{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
     4 int n,m,vis[505][505],h[505][505],a[505][505];
     5 struct node
     6 {
     7     int x,y,h;
     8     bool operator<(const node &b)const
     9     {
    10         return h>b.h;
    11     }
    12 };
    13 int x,y;
    14 void bfs()
    15 {
    16     priority_queue<node>q;
    17     node fir,nxt;
    18     fir.x=x;
    19     fir.y=y;
    20     fir.h=a[x][y];
    21     q.push(fir);
    22     while(!q.empty())
    23     {
    24         fir=q.top();q.pop();
    25         for(int i=0;i<8;i++)
    26         {
    27             int xx=fir.x+d[i][0];
    28             int yy=fir.y+d[i][1];
    29             if(xx<1||yy<1||xx>n||yy>m||vis[xx][yy]||a[xx][yy]>=0)   continue;
    30             nxt.x=xx;
    31             nxt.y=yy;
    32             nxt.h=max(fir.h,a[xx][yy]);
    33             h[xx][yy]=nxt.h;
    34             vis[xx][yy]=1;
    35             q.push(nxt);
    36         }
    37     }
    38     return ;
    39 }
    40 int main()
    41 {
    42     scanf("%d%d",&n,&m);
    43     for(int i=1;i<=n;i++)
    44     {
    45         for(int j=1;j<=m;j++)
    46         {
    47             scanf("%d",&a[i][j]);
    48         }
    49     }
    50     scanf("%d%d",&x,&y);
    51     h[x][y]=a[x][y];
    52     vis[x][y]=1;
    53     bfs();
    54     long long ans=0;
    55     for(int i=1;i<=n;i++)
    56     {
    57         for(int j=1;j<=m;j++)
    58         {
    59             ans+=-1LL*h[i][j];
    60         }
    61     }
    62     printf("%lld
    ",ans);
    63     return 0;
    64 }
    View Code

    G题:Galactic Collegiate Programming Contest

    模拟滚榜,在每个事件下面只看第一个队伍的排名,排名的规则是:The score of team t 1 is better than that of t 2 if either a1 > a2 , or if a1 = a2 and b1 < b2 . The rank of a team is k + 1 where k is the number of teams whose score is better. 注意:如果有一支队伍的出题数目和罚时都和第一支队伍相当,那么这支队伍会在第一支队伍下面,排名不会比第一支队伍高

    第一种方法是用multiset,把结构体放到multiset中并且重载'<'

    第二种方法是用优先队列,并且要用一个变量来表示当前优先队列的元素个数sum,还要有一个数组来判断当前队伍是否已经被放入队列里,最后再把不合法的队伍从队列里取出,并同时相应的改变sum的值和队伍的状态

    第三种方法是我们可以把出题数和罚时转换成相应的数值,我们会发现这些数值与一支队伍的出题数和罚时是相对应的。但我们要注意罚时要取差值。然后我们仍然可以用第一种方法,把数值放到multiset中。或者我们可以先离线,然后用树状数组

    给出第一种的代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 struct node
     5 {
     6     int t,p,pos;
     7     bool operator<(const node &b)const  //注意这个地方的重载,要理解
     8     {
     9         if(t==b.t)
    10         {
    11             if(p==b.p)
    12                 return pos>b.pos;
    13             return p>b.p;
    14         }
    15         return t<b.t;
    16     }
    17 }a[100005];
    18 multiset<node>s;  //multiset可支持重复元素
    19 int main()
    20 {
    21     int n,m;
    22     scanf("%d%d",&n,&m);
    23     for(int i=0;i<=n;i++)
    24     {
    25         a[i].t=0;
    26         a[i].p=0;
    27         a[i].pos=i;
    28     }
    29     int x,y;
    30 
    31     while(m--)
    32     {
    33         scanf("%d%d",&x,&y);
    34         if(x==1)
    35         {
    36             a[x].t++;
    37             a[x].p+=y;
    38         }
    39         else
    40         {
    41             if(a[1]<a[x])       //如果当前队伍原来已经在set里了,我们需要先把他删除
    42             {
    43                 s.erase(s.find(a[x]));//erase里一定要是要删除元素所对应的迭代器,因为我们只需要删除一个
    44                                         //如果传入的是这个元素,那么所有与它相等的元素都会被删除
    45             }
    46             a[x].t++;
    47             a[x].p+=y;
    48             s.insert(a[x]);
    49         }
    50         multiset<node>::iterator it;
    51         for(it=s.begin();it!=s.end();)//要注意这里的写法,for循环里不用写it++,因为我们规定的是排名比第一支队伍小的放在前面
    52                                         //所以我们应该是从前往后删除不合法的
    53         {
    54             if((*it)<a[1])
    55             {
    56                 s.erase(it++);  //特别注意这个地方的写法,erase里应该是it++!!!
    57             }
    58             else
    59                 break;
    60         }
    61         printf("%d
    ",s.size()+1);
    62     }
    63     return 0;
    64 }
    View Code

    I题:Judging Moose

    直接写

     1 #include <bits/stdc++.h>
     2  
     3 using namespace std;
     4 int a,b;
     5 int main()
     6 {
     7     scanf("%d%d",&a,&b);
     8     if(a==0&&b==0)
     9     {
    10         printf("Not a moose
    ");
    11         return 0;
    12     }
    13     if(a==b)
    14     {
    15         printf("Even %d
    ",a+b);
    16     }
    17     else
    18     {
    19         int maxn=max(a,b);
    20         printf("Odd %d
    ",2*maxn);
    21     }
    22  
    23     return 0;
    24 }
    25  
    View Code

    J题:Kayaking Trip

    二分+贪心

     1 #include <bits/stdc++.h>
     2  
     3 using namespace std;
     4 struct node
     5 {
     6     int first,second,sum;
     7 }op[10];
     8 int per[5],s[5],num[5];
     9 int n;
    10 int c[50050];
    11 bool check(int mid)
    12 {
    13     for(int i=1;i<=3;i++)
    14     {
    15         num[i]=per[i];
    16     }
    17     for(int i=1;i<=n;i++)
    18     {
    19         int flag=0;
    20         for(int j=1;j<=6;j++)
    21         {
    22             if(num[op[j].first]==0||num[op[j].second]==0||op[j].sum*c[i]<mid)
    23             {
    24                 continue;
    25             }
    26             if(op[j].first==op[j].second&&num[op[j].first]<2)
    27             {
    28                 continue;
    29             }
    30             num[op[j].first]--;
    31             num[op[j].second]--;
    32             flag=1;
    33             break;
    34         }
    35         if(flag==0)
    36         {
    37             return 0;
    38         }
    39     }
    40     return 1;
    41 }
    42 int main()
    43 {
    44     scanf("%d %d %d",&per[1],&per[2],&per[3]);
    45     scanf("%d %d %d",&s[1],&s[2],&s[3]);
    46     n=per[1]+per[2]+per[3];
    47     n/=2;
    48     for(int i=1;i<=n;i++)
    49     {
    50         scanf("%d",&c[i]);
    51     }
    52     sort(c+1,c+1+n);
    53     int k=1;
    54     for(int i=1;i<=3;i++)
    55     {
    56         for(int j=i;j<=3;j++)
    57         {
    58             op[k].first=i;
    59             op[k].second=j;
    60             op[k++].sum=s[i]+s[j];
    61         }
    62     }
    63     int r=400000000,l=0,mid,ans;
    64     while(r-l>=0)
    65     {
    66         mid=(r+l)/2;
    67         if(check(mid))
    68         {
    69             ans=mid;
    70             l=mid+1;
    71         }
    72         else
    73         {
    74             r=mid-1;
    75         }
    76     }
    77     printf("%d
    ",ans);
    78     return 0;
    79 }
    View Code

    如有错误,请指正,感谢!
  • 相关阅读:
    优先队列(堆)
    从CPU管理到进程的引入
    倾听程序员
    数据库设计
    数据库设计之数据库,数据表和字段等的命名总结
    Set容器--HashSet集合
    Java Collection开发技巧
    关于事务
    关于触发器
    windows phone(成语典籍游戏开发)
  • 原文地址:https://www.cnblogs.com/scott527407973/p/9564244.html
Copyright © 2020-2023  润新知