牛客小白月赛55
A 至至子的等差中项
#include<bits/stdc++.h>
using namespace std;
int32_t main(){
int a , b;
cin >> a >> b;
cout << b * 2 - a << "\n";
}
B 至至子的按位与
如果在二进制下按位考虑。如果a,b
某位都是1
的话c
的这一位自然也是1。如果都是0的话,c
选0,1
都可但是尽可能的大所以选择1
。如果不相同的情况就只能选择0
了。
#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 a = read() , b = read() , c = 0;
vector<int> v;
for( int i = 0 ; i < 63 ; i ++ ){
if( (a&1) == (b&1) ) c += ( 1ll << i );
a >>= 1 , b >>= 1 ;
}
cout << c << "\n";
}
C 至至子的斐波那契
斐波那契第88项就大于1e18
了,所以先计算出足够长斐波那契数列,然后对于每个询问二分就好了
#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 = 2;
vector<int> feb;
feb.push_back(0) , feb.push_back(1) ,feb.push_back(1);
for( ; feb.back() < 1e18 ; n ++ )
feb.push_back( feb[n] + feb[n-1] );
for( int T = read() , x , t ; T ; T -- ){
x = read();
t = lower_bound( feb.begin() , feb.end() , x ) - feb.begin();
if( feb[t] - x >= x - feb[t-1] ) t --;
cout << t << "\n";
}
}
D 至至子的鸿门宴
一共只能取\(\sum_i=1^n(a_i-i)\)个,每次只能取一个。易知取的顺序没有影响,所以一共能取奇数个先手必胜。
#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 sum = 0 , n = read();
for( int i = 1 , a ; i <= n ; i ++ )
a = read() - i , sum += a;
if( sum & 1 ) cout << "ZZZ\n";
else cout << "SSZ\n";
}
E 至至子的长链剖分
这是一个构造题目,要构造一棵树,每一个点有一个权值,且父节点的权值必须比子节点大,叶子节点权值只能为零。
那么首先我们就要先找到根节点,发现如果根节点不唯一,这无解。
然后我们判断每一个权值为i
的节点数如果比i-1
少,那么一定无解。
再次基础上,我们按照全职递减的方法连成多个链,把每一条链都插在根节点上就好。
#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;
}
const int N = 2e5+5;
int fa[N] ;//每个节点的父亲
vector<int> h[N];//每种权值点的集合
void solve(){
int n = read() , m = -1;
fill( fa+1 , fa+1+n , 0 );
fill( h , h+1+n , vector<int>() );
for( int i = 1 , x ; i <= n ; i ++ )
x = read() , h[x].push_back(i) , m = max( m , x );
if( h[m].size() > 1 ){
cout << "-1\n";
return;
}
for( int i = 2 ; i <= m ; i ++ )
if( h[i].size() > h[i-1].size() ) {
cout << "-1\n";
return;
}
int root = h[m][0];
fa[root] = root , h[m].pop_back();
while( m >= 0 ){
while( h[m].empty() ) m --;
if( m < 0 ) break;
int f = h[m].back();//链的起点
fa[f] = root , h[m].pop_back();
for( int i = m - 1 , t ; i >= 0 ; i -- )//构造链
t = h[i].back() , h[i].pop_back() , fa[t] = f , f = t;
}
cout << root << "\n";
for( int i = 1 ; i <= n ; i ++ )
if( fa[i] != i ) cout << fa[i] << " " << i << "\n";
}
int32_t main() {
for( int T = read() ; T ; T -- )
solve();
}