2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)

Posted Lnn.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)相关的知识,希望对你有一定的参考价值。

前言:单人写了一下,只写出了4题,大概铜中的水准。疯狂wawawa。

文章目录

D. Bits Reverse

题目传送门


  题目类型:二进制、位运算
  解析: ABC倒置为CBA其实就是隔一位交换、那么奇数位可以互换、偶数位可以互换;分别看一下奇偶位1数量是否一样,然后贪心取。
  code:

#include <bits\\stdc++.h>
#define Lnnnb return 0;
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
#define maxn 202020

using namespace std;
void eninit();
ll n,x,y,ttt;
ll xnt,ynt,xon[70],yon[70];

void finit()



void scan()
    cin >> x >> y ;


ll add(ll ned)
    xnt = ynt = 0;
    ll m = x , res = 0;
    for(ll i = 1 ; m ; ++i , m /= 2)
        if(i%2 == ned && m%2 == 1)xon[++xnt] = i;
    
    m = y;
    for(ll i = 1 ; m ; ++i , m /= 2)
        if(i%2 == ned && m%2 == 1)yon[++ynt] = i;
    
    if(xnt != ynt)return -1;
    for(ll i = 1 ; i <= xnt ; ++i)
        res += abs(xon[i] - yon[i])/2;
    
    return res;


void solve()
    ll res1 = 0 , res0 = 0;
    res1 = add(1);
    res0 = add(0);
    if(res1 == -1 || res0 == -1)
        cout << "Case " << ttt << ": " << -1 << endl ;
        return;
    
    cout << "Case " << ttt << ": " << res1 + res0 << endl ;


int main()
    ios::sync_with_stdio(false);
    ///cin.tie(0);cout.tie(0);
    finit();
    ll t = 1;
    cin >> t ;
    for(ttt = 1 ; ttt <= t ; ++ttt)
        scan();
        solve();
        eninit();
    
    Lnnnb


void eninit()


H. Hamming Distance

  题目类型:字符串、字典序、贪心
  解析:因为字典序最小、尽量从前面贪心。如果两个位置字符一样,那就直接放a;不一样的单独处理,从前向后,看看后面的不同位置够不够将汉明距离变为0,够就放a,刚好就放b或者c,不够就只能补给汉明距离大的字符串。
  code:

#include <bits\\stdc++.h>
#define Lnnnb return 0;
#define ll long long
#define endl '\\n'
#define mem(a) memset(a,0,sizeof(a))
#define maxn 1010101

using namespace std;
void eninit();
ll n,ttt,dif[maxn];
char a[maxn],b[maxn],s[maxn];

void finit()



void scan()
    cin >> a+1 ;
    cin >> b+1 ;
    n = strlen(a+1);


void solve()
    ll dnt = 0 , lval = 0 , rval = 0;
    for(ll i = 1 ; i <= n ; ++i)
        if(a[i] == b[i])s[i] = 'a';
        else 
            dif[++dnt] = i;
        
    
    for(ll iii = 1 ; iii <= dnt ; ++iii)
        ll x = dif[iii];
        if(a[x] != 'a' && b[x] != 'a')
            if(abs(lval-rval) <= dnt - iii)
                s[x] = 'a';
            else 
                if(lval > rval)
                    s[x] = a[x];
                    rval++;
                else 
                    s[x] = b[x];
                    lval++;
                
            
        else 
            a[x] == 'a' ? rval++ : lval++ ;
            if(abs(lval-rval) <= dnt - iii)          ///只要差值<=剩下的不同的
                s[x] = 'a';
            else 
                a[x] == 'a' ? rval-- : lval--;        ///先不取a

                if(abs(lval-rval) == dnt - iii)      ///保持不变
                    if(a[x] != 'b' && b[x] != 'b')
                        s[x] = 'b';
                    else 
                        if(lval > rval && a[x] == 'b')s[x] = 'b' , rval++;
                        else if(lval < rval && b[x] == 'b')s[x] = 'b' , lval++;
                        else s[x] = 'c';
                    
                else                                ///差太大了
                    if(lval > rval)
                        s[x] = a[x];
                        rval++;
                    else 
                        s[x] = b[x];
                        lval++;
                    
                

            
        
    
    cout << "Case " << ttt << ": " << s+1 ;

///cout << "Case " << ttt << ": " <<  ;

int main()
    ios::sync_with_stdio(false);
    ///cin.tie(0);cout.tie(0);
    finit();
    ll t = 1;
    cin >> t ;
    for(ttt = 1 ; ttt <= t ; ++ttt)
        scan();
        solve();
        eninit();
        if(ttt != t)cout << endl ;
    
    Lnnnb


void eninit()
    for(ll i = 0 ; i <= n+10 ; ++i)
        a[i] = b[i] = s[i] = 0;
    


G. Greatest Common Divisor

  题目类型:gcd、差分
  解析:(应该能很自然的想到差分数组不变把 )为什么差分呢:想象一下,将数组排序后,假设差分数组的gcd = g。那么只要a1是g的倍数,a[i] = a[1]+k*g,就都是g的倍数。g的因子同理,所以就枚举g的因子yz,看看a1变为yz需要加多少次即可。
  code:

#include <bits\\stdc++.h>
#define Lnnnb return 0;
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
#define maxn 202020

using namespace std;
void eninit();
ll n,ttt;
ll a[maxn];
ll gcd(ll aa,ll bb)
    return bb == 0 ? aa : gcd(bb,aa%bb);


void finit()



void scan()
    cin >> n ;
    for(ll i = 1 ; i <= n ; ++i)
        cin >> a[i] ;
    


void solve()
    sort(a+1,a+1+n);
    ll g = 0 , ji = 1;
    for(ll i = 1 ; i <= n ; ++i)
        g = gcd(g , a[i]);
        if(a[i]%2 == 0)ji = 0;
    
    if(g > 1)
        cout << "Case " << ttt << ": " << 0 << endl ;
        return;
    
    if(ji)
        cout << "Case " << ttt << ": " << 1 << endl ;
        return;
    
    ll cha = 0;
    for(ll i = 1 ; i <= n-1 ; ++i)
        if(a[i+1] - a[i] == 0)continue;
        cha = gcd(cha , a[i+1] - a[i]);
    
    if( cha == 1 )
        cout << "Case " << ttt << ": " << -1 << endl ;
        return;
    
    ll ans = 4e18;

    for(ll i = 2 ; i*i <= cha ; ++i)
        if(cha %i == 0)
            ll x = i , y = cha/i;
            ans = min(ans , (x - a[1]%x)%x );
            ans = min(ans , (y - a[1]%y)%y );
        
    
    ans = min(ans , (cha - a[1]%cha)%cha );
    cout << "Case " << ttt << ": " << ans << endl ;


int main()
    ios::sync_with_stdio(false);
    ///cin.tie(0);cout.tie(0);
    finit();
    ll t = 1;
    cin >> t ;
    for(ttt = 1 ; ttt <= t ; ++ttt)
        scan();
        solve();
        eninit();
    
    Lnnnb


void eninit()



J. Stone Game

  题目类型:博弈、拓扑排序
  解析:此题胜负完全不由决策决定。因为相邻的数不相同,所以总会有a[i]满足a[i-1] > a[i] && a[i+1] > a[i],那么a[i]就可以变为0。
  这个数组相当于相邻的数有一条边,小的指向大的数,一个有向无环图,所以比两边都小的加入队列,逐步减少其他点的入度,拓扑排序一下即可。
  比如:2 3 4 1
  第一个数和第四个数可以变成0:0 3 4 0
  第二个数变成1:0 1 4 0
  第三个数变成2:0 1 2 0
  计算新数组和原来数组的差值和,奇数A赢,偶数B赢。
  code:

#include <bits\\stdc++.h>
#define Lnnnb return 0;
#define ll long long
#define endl '\\n'
#define mem(a) memset(a,0,sizeof(a))
#define maxn 1010101

using namespace std;
void eninit();
ll n,ttt;
ll a[maxn],c[maxn],vis[maxn];
queue<ll>q;

void finit()



void scan()
    cin >> n ;
    for(ll i = 1 ; i <= n ; ++i)
        cin >> a[i] ;
    


ll check(ll i)
    ll lf = (a[i-1] > a[i] || vis[i-1]);
    ll rg = (a[i+1] > a[i] || vis[i+1]);
    return (lf && rg);


void solve()
    ll sum = 0;
    a[0] = a[n+1] = 1e9;
    vis[0] = vis[n+1] = 1;
    for(ll i = 1 ; i <= n ; ++i)
        if(a[i-1] > a[i] && a[i] < a[i+1] && !vis[i])
            q.push(i);
        
    
    while(!q.empty())
        ll top = q.front();
        q.pop();
        vis[top] = 1;
        ll l = top-1 , r = top+1;
        if(!vis[l] && check(l))
            vis[l] = 1;
            q.push(l);
            c[l] = max(c[l-1] , c[l+1]) + 1;
        
        if(!vis[r] && check(r))
            vis[r] = 1;
            q.push(r);
            c[r] = max(c[r-1] , c[r+以上是关于2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)的主要内容,如果未能解决你的问题,请参考以下文章

Fight Against Monsters (2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest)(T

2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)

2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)

2018 China Collegiate Programming Contest - Guilin Site(D/H/G/J/A)

Rolling The Polygon (2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest)(The

2018-2019 ACM-ICPC, China Multi-Provincial Collegiate G. Factories(树形dp+算贡献)