Codeforces Round 951 (Div. 2)

A: Guess the Maximum

Alice and Bob came up with a rather strange game. They have an array of integers a 1 , a 2 , … , a n a_1, a_2,\ldots, a_n a1,a2,,an. Alice chooses a certain integer k k k and tells it to Bob, then the following happens:

  • Bob chooses two integers i i i and j j j ( 1 ≤ i < j ≤ n 1 \le i < j \le n 1i<jn), and then finds the maximum among the integers a i , a i + 1 , … , a j a_i, a_{i + 1},\ldots, a_j ai,ai+1,,aj;
  • If the obtained maximum is strictly greater than k k k, Alice wins, otherwise Bob wins.

Help Alice find the maximum k k k at which she is guaranteed to win.

题意:

爱丽丝和鲍勃想出了一个相当奇怪的游戏。他们有一个整数数组 a1,a2,…,an。爱丽丝选择了某个整数 k 并告诉了鲍勃,然后就发生了下面的事情:

鲍勃选择两个整数 i 和 j (1≤i<j≤n),然后找出整数 ai,ai+1,…,aj中的最大值;
如果得到的最大值严格大于 k,则爱丽丝获胜,否则鲍勃获胜。帮助爱丽丝找出最大值 k ,保证她赢。

分析:

遍历数组,找到每两个值中的较大值,再取较大值中的最小值,得到ans,ans-1即为答案。

代码:

#include<bits/stdc++.h>
using namespace std;
 
const int N =5*1e4+10;
int a[N];
 
int main()
{
	int tt;
	cin >> tt;
	while(tt--)
	{
		int n;
		cin >> n;
		for(int i=1;i<=n;i++) cin >> a[i]; 
		int ans=1e9;
		for(int i=1;i<n;i++)
		{
			ans=min(ans,max(a[i],a[i+1]));
		}
		cout << ans-1 << endl;
	}
	return 0;
 } 

B: XOR Sequences

You are given two distinct non-negative integers x x x and y y y. Consider two infinite sequences a 1 , a 2 , a 3 , … a_1, a_2, a_3, \ldots a1,a2,a3, and b 1 , b 2 , b 3 , … b_1, b_2, b_3, \ldots b1,b2,b3,, where

  • a n = n ⊕ x a_n = n \oplus x an=nx;
  • b n = n ⊕ y b_n = n \oplus y bn=ny.

Here, x ⊕ y x \oplus y xy denotes the bitwise XOR operation of integers x x x and y y y.

For example, with x = 6 x = 6 x=6, the first 8 8 8 elements of sequence a a a will look as follows: [ 7 , 4 , 5 , 2 , 3 , 0 , 1 , 14 , … ] [7, 4, 5, 2, 3, 0, 1, 14, \ldots] [7,4,5,2,3,0,1,14,]. Note that the indices of elements start with 1 1 1.

Your task is to find the length of the longest common subsegment † ^\dagger of sequences a a a and b b b. In other words, find the maximum integer m m m such that a i = b j , a i + 1 = b j + 1 , … , a i + m − 1 = b j + m − 1 a_i = b_j, a_{i + 1} = b_{j + 1}, \ldots, a_{i + m - 1} = b_{j + m - 1} ai=bj,ai+1=bj+1,,ai+m1=bj+m1 for some i , j ≥ 1 i, j \ge 1 i,j1.

† ^\dagger A subsegment of sequence p p p is a sequence p l , p l + 1 , … , p r p_l,p_{l+1},\ldots,p_r pl,pl+1,,pr, where 1 ≤ l ≤ r 1 \le l \le r 1lr.

题意:

给你两个不同的非负整数 x和 y。考虑两个无穷序列 a1,a2,a3,…和 b1,b2,b3,…,其中an=n⊕x ;bn=n⊕y .这里, x⊕y 表示整数 x 和 y 的 bitwiseXOR 运算。
例如,有了 x=6之后,序列 a的前8个元素将如下所示:[7,4,5,2,3,0,1,14,…].请注意,元素的索引是从1开始的。
你的任务是找出序列 a和 b 的最长公共子段†的长度。换句话说,在某个 i,j≥1中,找出 ai=bj,ai+1=bj+1,…,ai+m−1=bj+m−1的最大整数 m。

†序列 p的一个子段是序列 pl,pl+1,…,pr,其中1≤l≤r。

分析:

根据观察和分析,最长公共子序列的长度与x,y的二进制数据进行bitwiseXOR 运算的结果有关。
当a=0,b=1时,a1=00,b1=01,运算结果为01,最长公共子段长度为1(1);
当a=12,b=4时,a1=1100,b1=0100,运算结果为1000,最长公共子段长度为8(1000);
当a=57,b=37时,a1=0011 1001,b1=0010 0101,运算结果为0001 1100,最长公共子段长度为4(100)……
总结可得,最长公共子段的长度即为a与b二进制进行bitwiseXOR 运算的结果
从最低位向高位第一个为1代表的数值。

代码:

#include<bits/stdc++.h>
using namespace std;
 
const int N =5*1e4+10;
int a[N];
 
int main()
{
	int tt;
	cin >> tt;
	while(tt--)
	{
		int x,y;
		cin >> x >> y;
		int a[50]={0},b[50]={0};
		int i=0,j=0;
		while(x)
		{
			a[i++]=x%2;
			x/=2;
		}
		while(y)
		{
			b[j++]=y%2;
			y/=2;
		}
		long long int ans=1;
		for(int k=0;k<=max(i,j);k++)
		{
			if(a[k]!=b[k])
			{
				cout << ans << endl;
				break;
			}
			else
			ans*=2;
		}
	}
	return 0;
 } 

C: Earning on Bets

You have been offered to play a game. In this game, there are n n n possible outcomes, and for each of them, you must bet a certain integer amount of coins. In the event that the i i i-th outcome turns out to be winning, you will receive back the amount of coins equal to your bet on that outcome, multiplied by k i k_i ki. Note that exactly one of the n n n outcomes will be winning.

Your task is to determine how to distribute the coins in such a way that you will come out ahead in the event of any winning outcome. More formally, the total amount of coins you bet on all outcomes must be strictly less than the number of coins received back for each possible winning outcome.

题意:

有人提议让您玩一个游戏。在这个游戏中,有 n种可能的结果,对于每一种结果,您都必须下注一定整数的硬币。如果 ai的结果是赢,您将获得与该结果投注额相等的硬币,再乘以 ki。请注意, n个结果中只有1个结果是赢的。

您的任务是确定如何分配硬币,以便在出现任何获胜结果时您都能获胜。更正式地说,你在所有结果上投注的硬币总数必须严格地小于每个可能获胜的结果所得到的硬币数量。

分析:

即我们需要找到数组中所有元素的最小公倍数s,用s除于每一个元素得到相应的投注额。最后再判断所有投注额的和是否严格小于最小的获胜收益。

代码:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long int LL;
const int N =110;
LL a[N],b[N];
 
LL gcd(LL x,LL y)
{
	if(y==0)
	{
		return x;
	}
	return gcd(y,x%y);
}
LL LCM(LL x,LL y)
{
	return (x*y)/gcd(x,y);
}
int main()
{
	int tt;
	cin >> tt;
	while(tt--)
	{
		int n;
		cin >> n;
		for(int i=1;i<=n;i++)
		cin >> a[i];
		LL ans=a[1],flag=0;
		for(int i=2;i<=n;i++)
		{
			ans=LCM(min(ans,a[i]),max(a[i],ans));
		}
		for(int i=1;i<=n;i++)
		{
			b[i]=ans/a[i];
			flag+=b[i];
		}
		if(ans>flag)
		{
			for(int i=1;i<=n;i++)
			{
				cout << b[i] << ' ';
			}
			cout << endl;
		}
		else
		cout << -1 << endl;
	}
	return 0;
 } 

24/6/7

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值