AtCoder Beginner Contest 273

A - A Recursive Function

签到题

#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 = 1e5+5;
int n , res , v[N] ;

int f( int x ){
    if( x == 0 ) return 1;
    return x * f( x - 1 );
}
int32_t main() {
    cin >> n;
    cout << f(n) << "\n";
}

B - Broken Rounding

这道题题的意思其实就是反复地进行四舍五入

#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;
}


int32_t main() {
    int n = read() , x = read() , m = x ;
    for(  int i = 1 ; i <= x ; i ++ )
        n = ( n + 5 ) / 10 ;
    cout << n ;
    if( n == 0 )return 0;
    for( int i = 1 ; i <= x ; i ++ )
        cout << 0;

}

C - (K+1)-th Largest Number

这道题的题意是统计出对于每一个位置上的数在整个序列中有多少种数比他大

所以把整个拷贝序列排序,去重后对于原序列在处理后的序列二分查找一下位置即可

#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;
int a[N] , n , b[N] , m , c[N];

int32_t main() {
    n = read();
    for( int i = 1 ; i <= n ; i ++ )
        b[i] = a[i] = read();
    sort( b + 1 , b + 1 + n ) , m = unique( b+1 , b+1+n ) - b - 1;
    for( int i = 1 , t; i <= n ; i ++ ){
        t = m - ( upper_bound( b+1 , b+1+m , a[i] ) - b - 1 );
        if( t == -1 ) t = 0;
        c[t] ++ ;
    }
    for( int i = 0 ; i < n ; i ++ )
        cout << c[i] << "\n";
}

D - LRUD Instructions

最基础的做法就是模拟一下他走的过程,但是这样很容易会 TLE

所以我存下了每一行、每一列所有的障碍物,然后二分的查找当前移动方向上最近的障碍物时候会阻挡移动,如果会就移动到最远的地方,如果不能就直接移动到目标位置

#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;
int h , w  , n , q , sx , sy;

set< pair<int,int> > st;
map< int , vector<int> > tx , ty;

map< char , int > fx , fy;


pair<int,int>  next( pair<int,int> s , char d ){
    auto & [ x , y ] = s;
    return { x + fx[d] , y + fy[d] };
}

bool pending( pair<int,int> it ){
    auto &[ x , y ] = it;
    if( x < 1 || y < 1 || x > h || y > h ) return false;
    if( st.count({ x , y } ) ) return false;
    return true;
}

int32_t main() {
    int sx , sy;
    h = read() , w = read() , sx = read() , sy = read();
    n = read();
    for( int i = 1 , x , y ; i <= n ; i ++ ){
        x = read() , y = read();
        tx[x].push_back(y);
        ty[y].push_back(x);
    }
    for( auto &[ k , ve ] : ty )
        ve.push_back(0) , ve.push_back(h+1) , sort( ve.begin() , ve.end() );
    for( auto &[ k , ve ] : tx )
        ve.push_back(0) , ve.push_back(w+1) , sort( ve.begin() , ve.end() );
    q = read();
    for( auto [ d , l ] = pair<char,int>() ; q ; q -- ){
        cin >> d , l = read();

        if( d == 'L' ){
            if( tx.count(sx) == 0 ){
                sy = max( sy - l , 1ll );
            }
            else{
                auto t =  lower_bound( tx[sx].begin() , tx[sx].end() , sy ) - 1;
                if( *t < sy - l ) sy = sy - l;
                else sy = *t + 1;
            }
        }
        if( d == 'R' ) {
            if( tx.count( sx )  == 0 ){
                sy = min( sy + l , w );
            }
            else{
                auto t = lower_bound(tx[sx].begin(), tx[sx].end(), sy);
                if (*t > sy + l) sy = sy + l;
                else sy = *t - 1;
            }
        }
        if( d == 'U' ){
            if( ty.count( sy ) == 0 ){
                sx = max( 1ll , sx - l );
            }
            else {
                auto t = lower_bound(ty[sy].begin(), ty[sy].end(), sx) - 1;
                if (*t < sx - l) sx = sx - l;
                else sx = *t + 1;
            }
        }
        if( d == 'D' ){
            if( ty.count(sy) == 0 ){
                sx = min( h , sx + l );
            }
            else{
                auto t = lower_bound(ty[sy].begin(), ty[sy].end(), sx);
                if (*t > sx + l) sx = sx + l;
                else sx = *t - 1;
            }
        }
        cout << sx << " " << sy << "\n";

    }
    return 0;
}

E - Notebook

首先一个比较简单的想法就是用map<int,vector<int>>来模拟笔记本

显然这样的代码是不能通过的(实际上我用通过了 35 个点)

这里其实我们可以参考 Git的处理方法,每一次只存储修改就好。并且,我们发现这道题的修改和查询都是只在末尾进行操作。

所以我们可以这样来理解

  1. ADD新建一个版本
  2. DELETE回滚到上一个版本
  3. SAVE给当前版本打一个tag
  4. LOAD快速回滚到之前某一个

这样我们实际只需要保存每一个版本的末尾值是啥,以及当前版本的上一个版本号即可

#include<bits/stdc++.h>

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;
}

int32_t main() {
    int at = 0;
    vector< pair<int,int> >version;
    map< int , int > tag;
    version.push_back( { 0 , -1 } );
    for( int n = read() , x ; n ; n -- ){
        string s; cin >> s;
        if( s == "ADD"){
            x = read();
            version.push_back( { at , x } ) , at = version.size() - 1;
        }
        else if( s == "DELETE" ){
             at = version[at].first;
        }
        else if( s == "SAVE"){
            x = read();
            tag[x] = at;
        }
        else{
            x = read();
            at = tag[x];
        }
        cout << version[at].second << " ";
    }
    return 0;
}
posted @ 2022-10-17 19:51  PHarr  阅读(57)  评论(0编辑  收藏  举报