• Codeforces Round #588 (Div. 2) D. Marcin and Training Camp


    题目地址:http://codeforces.com/contest/1230/problem/D

    题意:有n个人,每个人有两个属性值a和b,ai表示第i人会的算法,2进制第j位为1的表示他会的(0<=j<60)。要组至少2人的队,当且仅当x知道某个y不知道的算法时,学生x认为他比学生y好。注意,两个学生可以认为他们比对方更好。如果这组学生中没有一个人认为自己比这组其他人都好,那么这组学生就可以平静地合作。问最大的b值之和。

    思路:队里会算法一定要有相同的,不然无法组队。找到所有有相同算法的人,再找每个相同算法包含的(if((a|x)==a)),加起来所有的b值输出即可。

    AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 const int N=7005;
     8 int n,a[N];
     9 struct nn{
    10     ll a,b;
    11 }t[N];
    12 int cmp(nn A,nn B){
    13     return A.a>B.a;
    14 }
    15 void sol(){
    16     sort(t,t+n,cmp);
    17     ll sum=0,aa[N]={0};
    18     int num=0,x=0;
    19     for(int i=1;i<n;i++){       //找相同的
    20         if(t[i].a==t[i-1].a){
    21             if(num==0) aa[x++]=t[i].a;
    22             num++;
    23             if(num>1) sum+=t[i].b,t[i].b=0;
    24             else sum+=t[i].b+t[i-1].b,t[i].b=0,t[i-1].b=0;
    25         }
    26         else num=0;
    27     }
    28     for(int i=0;i<x;i++){       //找包含的
    29         for(int j=0;j<n;j++){
    30             if((aa[i]|t[j].a)==aa[i]){
    31                 sum+=t[j].b;        //这里有重复计算,但肯定不会超时就没优化
    32                 t[j].b=0;
    33             }
    34         }
    35     }
    36     cout<<sum;
    37 }
    38 int main(){
    39     cin>>n;
    40     for(int i=0;i<n;i++)
    41         cin>>t[i].a;
    42     for(int i=0;i<n;i++)
    43         cin>>t[i].b;
    44     sol();
    45     return 0;
    46 }

     用容器写的,用不来所以感觉差别不大,不知道那些大佬的时间怎么那么短

     1 pair<ll,ll> A[N];
     2 vector<pair<ll,ll> >q;
     3 vector<ll>v;
     4 void sol2(){
     5     for(int i=0;i<n;i++)
     6         cin>>A[i].first;
     7     for(int i=0;i<n;i++)
     8         cin>>A[i].second;
     9     sort(A,A+n);
    10     ll sum=0;
    11     int num=0;
    12     A[n].first=-1;
    13     for(int i=1;i<=n;i++){
    14         if(A[i].first==A[i-1].first){
    15             sum+=A[i-1].second;
    16             num++;
    17         }
    18         else{
    19             q.push_back(A[i-1]);
    20             if(num!=0) {
    21                 v.push_back(A[i-1].first);
    22             }
    23             num=0;
    24         }
    25     }
    26     for(int i=0;i<v.size();i++){
    27         for(int j=0;j<q.size();j++){
    28             if((v[i]|q[j].first)==v[i]){
    29                 sum+=q[j].second;
    30                 q[j].second=0;
    31             }
    32         }
    33     }
    34     cout<<sum;
    35 }
  • 相关阅读:
    最小生成数kruskal算法和prim算法
    图的表示及遍历
    mysql忘记root用户密码重置密码的方式
    dwr2.0版本的demo
    web.xml中不同版本的servlet头以及版本控制
    初学jboss
    Filter学习总结,顺便提及点servlet3.0异步filter和异步监听
    监听器
    问题发现和解决
    linux学习
  • 原文地址:https://www.cnblogs.com/xunzf0402/p/11587061.html
Copyright © 2020-2023  润新知