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+算贡献)