A. Guess the Maximum
题意:
给定一个长度为n的整数数组,问数组中是否存在一个子数组满足子数组的最大值大于
k
k
k,若存在则爱丽丝获胜,否则鲍勃获胜,帮助爱丽丝找出最大值
k
k
k
,保证她赢。
题解:
遍历长度为 2 2 2的子数组,找出每个子数组的最大值,然后在最大值中找出最小值 − 1 -1 −1就是答案。
代码:
#include <iostream>
#include<algorithm>
using namespace std;
const int N=5e4+10;
int a[N];
void solve(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
int k=max(a[0],a[1]);
int x;
for(int i=0;i<n-1;i++){
x=max(a[i],a[i+1]);
k=min(k,x);
}
k--;
cout<<k<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
B. XOR Sequences
题意:
给出 x x x, y y y,若存在两个长度无穷数组 a a a和 b b b,满足 a i = i ⊕ x a_{i}=i \oplus x ai=i⊕x, b j = j ⊕ y b_{j}=j \oplus y bj=j⊕y,问数组 a a a和数组 b b b最长的公共子段的长度。
题解:
结论:将x和y写成对应的二进制数字,对应二进制字串最长的后缀长度为
t
t
t,则
2
t
2^t
2t即为答案。
证明:设
x
x
x的二进制串为
a
a
a,
y
y
y的二进制串为
b
b
b,
i
i
i的二进制串为
c
c
c,
j
j
j的二进制串为
d
d
d,对于相同的后缀只需要
c
i
=
d
i
c_{i}=d_{i}
ci=di(可以任取0/1),对于剩余的前缀只需要满足
c
i
⊕
d
i
c_{i} \oplus d_{i}
ci⊕di=
b
i
⊕
a
i
b_{i} \oplus a_{i}
bi⊕ai即可,a和b可能存在不止一个长度为
2
t
2^t
2t的公共子串。
代码:
#include <iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<math.h>
using namespace std;
#define int long long
const int N=50;
int a[N],b[N];
void solve(){
for(int i=0;i<=50;i++) a[i]=0,b[i]=0;
int x,y;
cin>>x>>y;
int count1=0,count2=0;
while(x){
a[count1]=x%2;
x/=2;
count1++;
}
while(y){
b[count2]=y%2;
y/=2;
count2++;
}
int ans=1;
for(int i=0;i<max(count1,count2);i++){
if(a[i]==b[i]) ans*=2;
else break;
}
cout<<ans<<endl;
}
signed main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
C. Earning on Bets
题意:
有人提议让您玩一个游戏。在这个游戏中,有
n
n
n 种可能的结果,对于每一种结果,您都必须下注一定整数的硬币。如果
i
i
i 的结果是赢,您将获得与您在该结果上所下注金额相等的硬币,再乘以
k
i
k_i
ki 。请注意,
n
n
n 个结果中只有
1
1
1个结果是赢的。
你的任务是决定如何分配硬币,以便在出现任何获胜结果时都能获胜。更正式地说,你在所有结果上投注的硬币总数必须**严格地小于每个可能获胜的结果所得到的硬币数量。
题解:
二分找出总下注的硬币数,然后根据规则分配即可。
代码:
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int N=110;
int a[N],b[N];
int n;
bool check(int x) {
int sum = x ;
for (int i = 1; i <= n; i ++) {
sum -= x / a[i];
}
return sum >= n;
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int l = n - 1, r = n * (int)1e9 + 1;
while(l<r){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
int ans=l;
int sum=ans;
if(ans==n-1||ans==n*(int)1e9+1){
cout<<"-1"<<endl;
return;
}
for(int i=2;i<=n;i++){
b[i]=ans/a[i]+1;
sum-=b[i];
}
b[1]=sum;
for(int i=1;i<=n;i++) cout<<b[i]<<" ";
cout<<endl;
}
signed main(){
int t;
cin>>t;
while(t--) solve();
return 0;
}