Educational Codeforces Round 50 (Rated for Div. 2) A 数学 B数学 C数位DP D双指针模拟

版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/82669676

A
Code:

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

int main(){
    LL n , k ; 
    cin >> n >> k ; 
    n = 2 * n + 1 ;
    n -- ; 
    n /= 2 ;
    LL num = k / n ;
    k %= n ; 
    if( k ) num ++  ;
    cout << num << endl;
    return 0 ; 
}

B
题意:从(0,0)走到(x,y) , 可以向上下左右左上左下右上右下这几个方向走,求用k步,最大能够斜着走的次数。k步(不多不少)不能达到则输出-1.
思路:可以处理成起点与终点(x,y)在一个对角线的问题,如果此时k-y是偶数步,那么到达终点时只需要一直沿着对角线来回走动即可。如果是奇数步,那么就在前面增减斜着走的数量以构造偶数。
Code:

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
int main(){
    LL k ;
    int q ;
    ios_base::sync_with_stdio(false); cin.tie(0) ; cout.tie(0) ; 
    LL x , y ; 
    cin >> q ;
    while( q-- ){
        LL num = 0LL ;
        cin >> x >> y >> k ; 
        if( x > k || y > k ){
            cout << -1 << endl;
        }else{
            if( x < y ) swap(x , y);  
            LL tmp = x - y ;
            num += tmp ;
            k -= tmp ; 
            if( k < 0 ) cout << -1 << endl;

            if( tmp % 2 ){
                if( k < y ){
                    cout << -1 << endl; continue; 
                }
                k -- ;
                if( (k-y) % 2 ){
                    k ++ ;
                    num -- ; 
                }
            }else{
                if( k < y ){
                    cout << -1 << endl; continue; 
                }
                if( (k-y) % 2 ){
                    if( !tmp ){
                        k -= 2;
                    }else{
                        num -- ;
                        k -- ;
                    }
                }
            }
            num += k ;
            if( k < 0 || num < -1 ) cout << -1 << endl;
            else cout << num << endl;
        }
    }
    return 0 ; 
}

C
题意:找出x-y中(包含x,y)除0以外数字少于等于3个的数的个数。
思路:数位dp,dp[pos][num]表示到pos位有num个非零数字。记得处理前导零即可。
Code:

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const int AX = 20+6;
int a[AX];
LL dp[AX][5];
LL dfs( int pos , int num , bool lead , bool lim ){
    if( pos == -1 ) return 1;
    if( !lim && !lead && dp[pos][num] != -1 ) return dp[pos][num];
    LL ans = 0;
    int up = lim ? a[pos] : 9 ;
    for( int i = 0 ; i <= up ; i++ ){
        if( num < 3 ){
            if( lead && !i ) ans += dfs( pos - 1 , num , lead, lim && i == a[pos]);
            else {
                if( !i ) ans += dfs( pos - 1 , num , lead && i == 0 , lim && i == a[pos] );
                else ans += dfs( pos - 1 , num + 1 , lead && i == 0 , lim && i == a[pos] );
            }
        }else if( num == 3 ){
            if( !i ) ans += dfs( pos - 1 , num , lead && i == 0 , lim && i == a[pos] );
        } 
    }
    if( !lim && !lead ) dp[pos][num] = ans;
    return ans ;
}

LL solve( LL x ){   
    int tot = 0 ;
    while( x ){
        a[tot++] = x % 10;
        x /= 10;
    }
    return dfs( tot - 1 , 0 ,  true , true );
}

int main(){
    int T;
    ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
    cin >> T ;
    LL l , r ; 
    memset( dp , -1 , sizeof(dp) ) ;
    while( T-- ){
        cin >> l >> r ;
        cout << ( solve(r) - solve(l-1) ) << endl;
    }
    return 0 ; 
}

D
题意:给2个数组,可以将连续的一段相加,要求求出最大长度,使得a和b数组完全一样。
思路:双指针模拟即可。
Code:

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const int AX = 3e5+666;
LL a[AX];
LL b[AX];
int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0) ; 
    int n , m ; 
    cin >> n ;
    for( int i = 0; i < n ; i++ ){
        cin >> a[i] ;
    }
    cin >> m ;
    for( int i = 0 ; i < m ; i++ ){
        cin >> b[i] ;
    }
    int cur_a = 0 , cur_b = 0 ; 
    int len = n ;
    int len1 = m ;
    while( cur_a < n && cur_b < m ){
        if( a[cur_a] < b[cur_b] ){
            LL tmp = a[cur_a] ; 
            while( cur_a < n && tmp < b[cur_b] ){
                cur_a ++ ;
                tmp += a[cur_a] ;
                len -- ;
            }
            a[cur_a] = tmp ;
        }else if( a[cur_a] > b[cur_b] ){
            LL tmp = b[cur_b] ; 
            while( cur_b < m && tmp < a[cur_a] ){
                cur_b ++ ;
                tmp += b[cur_b] ;
                len1 -- ; 
            }
            b[cur_b] = tmp ; 
        }else{
            cur_b ++ ; 
            cur_a ++ ;
        }
    }
    if( len == len1 && a[cur_a] == b[cur_b] ) cout << len << endl;
    else cout << -1 << endl;
    return 0 ; 
}

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/82669676