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

 

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\n",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\n");
11         return 0;
12     }
13     if(a==b)
14     {
15         printf("Even %d\n",a+b);
16     }
17     else
18     {
19         int maxn=max(a,b);
20         printf("Odd %d\n",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\n",ans);
78     return 0;
79 }
View Code

猜你喜欢

转载自www.cnblogs.com/scott527407973/p/9564244.html
今日推荐