AtCoder Beginner Contest 271

A - 484558

十进制转十六进制,签到题

#include<bits/stdc++.h>
#define int long long
using namespace std;

int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

void print( int x ){
    if( x < 10 )
        cout << x ;
    else
        cout << char( x - 10 + 'A' );
}

int32_t main(){
    int n , a , b;
    cin >> n;
    b = n % 16;
    a = n / 16;
    print(a) , print(b);
    return 0;
}

B - Maintain Multiple Sequences

读入多行数字,每次询问某一行某一列的数字,保证询问合法,这道题实际上很简单但是直接搞的话开不了呢么大的数组,用vector替代一下就好了

#include<bits/stdc++.h>
#define int long long
using namespace std;

int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

const int N = 2e5+5;


int32_t main(){
    int n = read() , q = read();
    vector a = vector< vector<int> >(n+1);
    for( int i = 1 , l ; i <= n ; i ++ ){
        l = read() , a[i].push_back(0);
        for( int j = 1 , x ; j <= l ; j ++ )
            x = read() , a[i].push_back(x);
    }
    for( int i , j ; q ; q -- ){
        i = read() , j = read();
        cout << a[i][j] << '\n';
    }
}

C - Manga

他有n本书,他可以卖掉任意两本,再购买一本新的,他必须从第一本开始看,依次看第二第三第四,问他最多可以看多少本书

首先重复的书都可以卖掉,其次如果当前要看的书没有可以卖掉后面的书来购买当前的数,贪心一下知道卖掉最后两本最优。

#include<bits/stdc++.h>
#define int long long
using namespace std;

int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

set<int> s;

int32_t main(){
    int n = read() , cnt = 0;
    for( int x ; n ; n -- ){
        x = read();
        if( s.count(x) ) cnt ++;
        else s.insert(x);
    }
    for( int i = 1 ; i ; i ++ ){
        if( s.count(i) ) s.erase(i);
        else{
            if( cnt >= 2 ) cnt -= 2;
            else if ( cnt >= 1 && s.size() >= 1 ){
                cnt -- , s.erase( *s.rbegin() );
            }
            else if( s.size() >= 2 ) {
                s.erase( *s.rbegin() ) , s.erase( *s.rbegin() );
            }
            else cout << i-1 , exit(0);
        }
    }
}

D - Flip and Adjust

N张卡片,正反面分别是AB,问是否可以在每张卡片都用的情况下组合出S

一道很基础的搜索加剪枝的题目。

通过 dfs 枚举选择那一面,然后i,sum表示选择到第i张卡片,且和为sum。把所有的状态插入到set中,如果之前出现过了,再次遇到就不用搜索了,因为后面的情况是完全相同的。

然后统计一下后缀最大值和后缀最小值,然后判断当前情况下,继续先后搜索是否可以包含S

以上两种剪枝就可以过这道题了

#include<bits/stdc++.h>
#define int long long
using namespace std;

int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

const int N = 105;

int n , s , top , down;
int a[N] , b[N] , c[N] , d[N];
set< pair<int,int> > st;

bitset<N> sta;

void dfs( int i , int sum ){
    if( st.count( { i , sum } ) ) return;
    st.insert( { i , sum } );
    if( sum + c[i] < s || sum + d[i] > s ) return;
    if( i == n + 1 ){
        if( sum == s ){
            cout << "Yes\n";
            for( int j = 1 ; j <= n ; j ++ )
                cout << (sta[j]?'H':'T');
            exit(0);
        }
        return;
    }
    sta[i] = 1 , dfs( i + 1 , sum + a[i] );
    sta[i] = 0 , dfs( i + 1 , sum + b[i] );
}

int32_t main(){
    n = read() , s = read();
    for( int i = 1 ; i <= n ;  i ++ )
        a[i] = read() , b[i] = read() , c[i] = max( a[i] , b[i] ) , d[i] = min( a[i] , b[i] );
    for( int i = n ; i >= 1 ; i -- )
        c[i] += c[i+1] , d[i] += d[i+1];
    dfs( 1 , 0 );
    cout << "No";
    return 0;
}
posted @ 2022-10-10 15:08  PHarr  阅读(40)  评论(0编辑  收藏  举报