ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

abc 247 题解

2022-05-24 17:00:20  阅读:120  来源: 互联网

标签:maxval abc minval int 题解 mid 247 ch right


A - Move Right

给一个四位的二进制,输出右移一位的结果

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

int n;
string s ;

int main()
{
    cin >> s;
    cout << '0';
    for( int i = 0 ; i <= 2 ; i ++ )
        cout << s[i];
}

B - Unique Nicknames

每一个人都有一个姓和一个名,要给每个人取一个昵称

昵称要满足两个条件,首先昵称必修与姓或名相同,其次昵称不能与其他人的姓或名相同

实际上把所有的所有的名和姓塞入到一个 map 中,只要一个人的名或姓是唯一的那么他就是可以起一个昵称

注意的是,会有人的名和姓相同

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

int n;
map<string , int> st;
string a[105] , b[105];

int main()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ ) {
        cin >> a[i] >> b[i];
        st[a[i]] ++ ;
        if( a[i] != b[i] ) st[b[i]] ++;
    }
    for( int i = 1 ; i <= n ; i ++ )
    {
        if( st[a[i]] == 1 || st[b[i]] == 1) continue;
        printf("No\n");
        return 0;
    }
    printf("Yes\n");
    return 0;
}

C - 1 2 1 3 1 2 1

题目给定了一个构造字符串的方法,\(s_i=s_{i-1}is_{i-1}\)

因为 n 很小直接构造就好

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

int n;
string s[20];

int main()
{
    cin >> n;
    s[1] = "1";
    for( int i = 2 ; i <= n ; i ++ )
        s[i] = s[i-1] + " " + to_string(i) + " " + s[i-1];
    cout << s[n];
    return 0;
}

D - Cylinder

首先给一个队列,然后有两种操作

  1. 插入 c 个 x
  2. 取出 c 个数并求和

如果单纯的模拟的话会 t,所以队列中存的是一个pair表示数和数的个数

然后每次我们取出一个pair如果有剩余的数就插回到队头,所以这里要用到双端队列

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

ll n , cnt;
deque< pair<ll,ll> > dq;

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

int main() {
    n = read();
    for( ll op , m , x , c ; n ; n -- ) {
        op = read();
        if (op == 1)
            x = read(), c = read(), dq.push_back({x, c});
        else {
            m = read(), cnt = 0;
            while (m) {
                x = dq.front().first, c = dq.front().second, dq.pop_front();
                if (c <= m)
                    cnt += x * c, m -= c;
                else
                    cnt += x * m , dq.push_front({x, c - m}) , m = 0;
            }
            printf("%lld\n", cnt);
        }
    }
    return 0;
}

E - Max Min

给定长度为 n 的序列,问有多少个区间的最大值最小值是 x 和 y

首先枚举一下左端点,然后二分出符合条件的最小值和最大值即可

那么如何判区间时候符合条件呢?实际上就是用线段树来维护一下区间最值就好了

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

const int N = 2e5+5;
int n , maxx , miny , a[N] ;
ll cnt ;

struct Node{
    int l , r , maxval , minval;
    Node *left , *right;
    Node( int l , int r , int maxval , int minval , Node * left , Node * right ) : l(l) , r(r) , maxval(maxval) , minval(minval) , left(left) , right(right){};
} *root;

Node * build( int l , int r )
{
    if( l == r ) return new Node( l , r , a[l] , a[l] , 0 , 0 );
    int mid = ( l + r ) >> 1;
    Node * left = build( l , mid ) , * right = build( mid + 1 , r );
    return new Node( l , r , max( left -> maxval , right -> maxval) , min( left -> minval , right -> minval ) , left , right );
}

void query( int l , int r , Node * cur , int &maxval , int &minval )
{
    if( l == cur -> l && r == cur ->r )
    {
        maxval = max( maxval , cur -> maxval ) , minval = min( minval , cur -> minval );
        return ;
    }
    int mid = ( cur -> l + cur -> r ) >> 1;
    if( l > mid ) query( l , r , cur -> right , maxval , minval );
    else if( r <= mid ) query( l , r , cur -> left , maxval , minval );
    else query( l , mid , cur -> left , maxval , minval ) , query( mid + 1 , r , cur -> right , maxval , minval );
}

ll erfen1( int x ){
    int l = x , r = n , mid , res = -1, maxval , minval;
    while( l <= r ){
        mid = (l+r)>>1 , maxval = -1 , minval = 0x7fffffff;
        query( x , mid , root , maxval , minval );
        if( maxval >= maxx && minval <= miny ) res = mid , r = mid - 1;
        else l = mid + 1;
    }
    if( res == -1 ) return -1;
    maxval = -1 , minval = 0x7fffffff , query( x  , res , root , maxval , minval );
    if(maxval == maxx && minval == miny ) return res;
    return -1;
}

ll erfen2( int x ){
    int l = x , r = n , mid , res = -1, maxval , minval;
    while( l <= r ){
        mid = (l+r)>>1 , maxval = -1 , minval = 0x7fffffff;
        query( x , mid , root , maxval , minval );
        if( maxval <= maxx && minval >= miny ) res = mid , l = mid + 1;
        else r = mid - 1;
    }
    if( res == -1 ) return -1;
    maxval = -1 , minval = 0x7fffffff , query( x  , res , root , maxval , minval );
    if(maxval == maxx && minval == miny ) return res;
    return -1;
}

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

int main() {
    n = read() , maxx = read() , miny = read();
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    root = build(1,n);
    for( ll i = 1 , l , r ; i <= n ; i ++ ){
        l = erfen1( i ) , r = erfen2(i);
        if( l != -1 && r != -1 ) cnt += r - l + 1;
    }
    cout << cnt << endl;
    return 0;
}

标签:maxval,abc,minval,int,题解,mid,247,ch,right
来源: https://www.cnblogs.com/PHarr/p/16306159.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有