练习赛8

A
签到,模拟

Code:

#include <bits/stdc++.h>
using namespace std;
int main(){
    int T;
    scanf("%d",&T);
    int n ;
    while( T-- ){
        scanf("%d",&n);
        int x ; 
        int a = 0 ;
        int b = 0 ;
        for( int i = 0 ; i < n ; i++ ){
            scanf("%d",&x);
            if( x == 1 ){
                a ++ ;
            }else if( x == 2 ){
                b++;
            }else if( x == 3 ){
                a ++;
                b ++ ;
            }else if( x== 4 ){
                a--;
                b--;
            }
        }
        if( a == b ){
            printf("Draw\n");
        }else if( a > b ){
            printf("Kobayashi\n");
        }else{
            printf("Tohru\n");
        }
    }
    return 0 ;
}

C
模拟。

Code:

#include <bits/stdc++.h>
using namespace std;
const int AX = 1e3+6;
map<string,int>mp;
map<int,string>mp1;
map<string,int>mp_q;
int main(){
    int T;
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> T;
    int n , q , c  ;
    while( T-- ){
        cin >> n >> q >> c;
        string s ;
        mp.clear();
        mp1.clear();
        mp_q.clear();
        int tot = 0;
        for( int i = 0 ; i < c ; i++ ){
            cin >> s;
            if( !mp[s] ){
                mp[s] = ++tot;
            }
            mp1[tot] = s;
        }
        int p[205][205];
        int num ;
        for( int j = 1 ; j <= tot; j++ ){
            for( int i = 0 ; i < q ; i++ ){
                p[j][i] = 0;
            }
        }
        for( int i = 0 ; i < q ;i ++ ){
            cin >> num;
            for( int j = 0 ; j < num ; j++ ){
                cin >> s;
                p[mp[s]][i] = 1 ;
            }
        }
        for( int i = 1 ; i <= tot ; i++ ){
            string temp;
            for( int k = 0 ; k < q ; k++ ){
                temp += ( p[i][k] ? '1' : '0' );
            }
            //cout << "s" << temp << endl;
            if( mp_q[temp] == 0 ){

                mp_q[temp] = i;
            }else{
                mp_q[temp] = -1;
            }
        }
        char c;
        string tmp;
        for( int i = 0 ; i < n ; i++ ){
            tmp = "";
            for( int j = 0 ; j < q ; j++ ){
                cin >> c;
                tmp += c;
            }
            if( mp_q[tmp] > 0 ){
                cout << mp1[mp_q[tmp]] << endl;
            }else{
                cout << "Let's go to the library!!" << endl;
            }
        }
    }
    return 0 ;
}

D

题意:给两个人的聊天日志,连续互相聊天大于等于m天则亲密度+1
思路:数据量下,暴力看区间交。

Code:

#include <bits/stdc++.h>
using namespace std;
const int AX = 1e3+6;
struct Node{
    int l , r ;
}a[AX],b[AX];
int main(){
    int T;
    scanf("%d",&T);
    int n , m , x , y ;
    while( T-- ){
        scanf("%d%d%d%d",&n,&m,&x,&y);
        for( int i = 0 ; i < x ; i++ ){
            scanf("%d%d",&a[i].l,&a[i].r);
        }
        for( int i = 0 ; i < y ; i++ ){
            scanf("%d%d",&b[i].l,&b[i].r);
        }
        int res = 0;
        for(int i = 0 ; i < x ; i++ ){
            for(int j = 0 ; j < y ; j++ ){
                if( a[i].r < b[j].l || a[i].l > b[j].r ) continue;
                int l = max( a[i].l , b[j].l );
                int r = min( a[i].r , b[j].r );
                int len = r - l + 1 ;
                if( len >= m ) res += (len - m) + 1 ;
            }
        }
        printf("%d\n",res);
    }
    return 0 ;
}

F

题意:序列 S={s1,s2,…,sn} 被称为 heapable ,当且仅当存在一个二叉树 T , n 个点均作为 T 的一个节点,且满足任意非根节点 si 和其父节点 sj , sj≤si 且 j< i 。现在有一个序列 a1,a2,…,an ,相应将其分成若干个 heapable 的子序列,问使得子序列个数最少的策略。
思路:贪心+STL,每次找比它小的最大元素,当它的子节点,如果不存在,自己是根。
Code:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 1e5+66;
int n;
struct Node{
    int val;
    int cnt ;
    int fa;
    Node(int val,int cnt,int fa):val(val),cnt(cnt),fa(fa){}
    bool friend operator < ( const Node &a , const Node &b ){
        return a.val < b.val;
    }
};
vector<int> v[AX];
multiset<Node>s;
multiset<Node>::iterator it;
int main(){
    int T;
    scanf("%d",&T);
    while( T -- ){
        s.clear();
        scanf("%d",&n);

        for( int i = 0 ; i <= n ; i++ ) v[i].clear();

        int num = 0 ;
        int x ;
        scanf("%d",&x);
        s.insert( Node(x,0,++num) );
        v[num].push_back(1);

        for( int i = 2 ; i <= n ; i++ ){
            scanf("%d",&x);

            it = s.upper_bound(Node(x,0,0));
            if( it == s.begin() ){
                s.insert(Node(x,0,++num));
                v[num].push_back(i);
            }else{
                it --;
              Node tmp = *(it);
              s.erase(it) ;
              s.insert( Node(x,0,tmp.fa) );
              v[tmp.fa].push_back(i);
              if(tmp.cnt==0) s.insert(Node(tmp.val,1,tmp.fa));
          }

      }

      printf("%d\n",num);
      for( int i = 1 ; i <= num ; i++ ){
        int len = v[i].size();
        printf("%d",len);
        for( int j = 0 ; j < len ; j++ ){
            printf(" %d",v[i][j]);
        }printf("\n");
    }

}
return 0 ;
}

I

题意:0表示女生,1表示男生。第i个人拥有i个宝石。将boy分到3,4组中。girl分到1,2组并且还要满足1 ,3 组宝石等于2,4组
思路:将一半的宝石给1,3组,剩下的给2,4.
我是记录前缀和,然后找是否存在一个位置的前缀和能够有前面某一个前缀和+一半的宝石 得到,能得话,这个区间的和就是一半宝石数,然后是0分1组,是1分3组,剩下的分到2,4即可/
Code:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int AX = 1e6+666;
char s[AX];

map<LL,int>mp;
map<LL,int>mp2;
int main(){
    int T;
    scanf("%d",&T);
    int n ;
    while( T-- ){
        scanf("%d",&n);
        scanf("%s",s);
        LL ans ;
        if( n % 2 ) ans = (LL)( n + 1 ) / 2LL * (LL)n ;
        else ans = (LL)n / 2LL * (LL)( n + 1 ) ;

        if( ans % 2 == 1 ){
            printf("-1\n");
            continue;
        }

        mp.clear();
        mp2.clear();
        LL sum = 0LL;
        for( int i = 1 ; i <= n ; i++ ){
            sum += i;
            mp[sum] = i ;
        }

        LL tmp = ans / 2;
        sum = 0LL;
        int l = -1 , r = -1 ;
        for( int i = 1 ; i <= n ; i++ ){
            sum += i ;
            if( sum > tmp ) break;
            if( mp[tmp + sum] ){
                l = i  ;
                r = mp[tmp+sum] - 1 ;
                break;
            }
        }

        if( l != -1 && r != -1 ){
            for( int i = l ; i <= r ; i++ ){
                if( s[i] == '0' ){
                    mp2[i] = 1;
                }else{
                    mp2[i] = 3;
                }
            }
        }else {
            printf("-1\n");
            continue;
        }

        for(int i = 0 ; i < n ; i++ ){
            if( mp2[i] == 1 ) printf("1");
            else if( mp2[i] == 3 ) printf("3");
            else{
                if( s[i] == '1' ) printf("4");
                else printf("2");
            }
        }printf("\n");

    }
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值