Week 1 日常训练(补题)

这篇博客介绍了多个算法题目,包括判断能否通过移动点使其成为连续整数段的问题,以及数组操作和数论相关题目。通过对输入输出样例的分析,解释了判断条件和解题思路,适合算法爱好者和程序员参考。
摘要由CSDN通过智能技术生成

CF1671B

题目描述

You are given nn points with integer coordinates on a coordinate axis OXOX . The coordinate of the ii -th point is x_ixi​ . All points' coordinates are distinct and given in strictly increasing order.

For each point ii , you can do the following operation no more than once: take this point and move it by 11 to the left or to the right (i..e., you can change its coordinate x_ixi​ to x_i - 1xi​−1 or to x_i + 1xi​+1 ). In other words, for each point, you choose (separately) its new coordinate. For the ii -th point, it can be either x_i - 1xi​−1 , x_ixi​ or x_i + 1xi​+1 .

Your task is to determine if you can move some points as described above in such a way that the new set of points forms a consecutive segment of integers, i. e. for some integer ll the coordinates of points should be equal to l, l + 1, \ldots, l + n - 1l,l+1,…,l+n−1 .

Note that the resulting points should have distinct coordinates.

You have to answer tt independent test cases.

输入格式

The first line of the input contains one integer tt ( 1 \le t \le 2 \cdot 10^41≤t≤2⋅104 ) — the number of test cases. Then tt test cases follow.

The first line of the test case contains one integer nn ( 1 \le n \le 2 \cdot 10^51≤n≤2⋅105 ) — the number of points in the set xx .

The second line of the test case contains nn integers x_1 < x_2 < \ldots < x_nx1​<x2​<…<xn​ ( 1 \le x_i \le 10^61≤xi​≤106 ), where x_ixi​ is the coordinate of the ii -th point.

It is guaranteed that the points are given in strictly increasing order (this also means that all coordinates are distinct). It is also guaranteed that the sum of nn does not exceed 2 \cdot 10^52⋅105 ( \sum n \le 2 \cdot 10^5∑n≤2⋅105 ).

输出格式

For each test case, print the answer — if the set of points from the test case can be moved to form a consecutive segment of integers, print YES, otherwise print NO.

题意翻译

给出 nn 个数 x_1, x_2, \ldots, x_nx1​,x2​,…,xn​,保证序列 xx 严格递增。对于每个数 x_ixi​,这个数只能选择改变成 x_i - 1xi​−1 或 x_i + 1xi​+1,当然,也可以不变。问能不能使所有数构成一个连续整数段。可以输出 \text{YES}YES,否则输出 \text{NO}NO。

输入输出样例

输入 #1复制

5
2
1 4
3
1 2 3
4
1 2 3 7
1
1000000
3
2 5 6

输出 #1复制

YES
YES
NO
YES
YES
即给出出一个严格递增序列,求是否可以通过+1-1使其成为等差数列,d=1。对于一个连续的等差数列,效果和一个数相同,不难发现,连续两个数若相差>=3,那么是肯定不符合题意。当相差>=2时,若存在两处这种情况,假设为a-b-c每个子序列边界相差为2,则对于b而言,只能+1或-1,所以这种情况也显然不符合,若一边差1而另一边差2,也显然不合题意,所以,只需对序列之间计算差值,sum+=差值-1,最后通过sum进行判断即可,sum显然只能<=2才符合题意。
#include<iostream>
using namespace std;

int t,n,sum,a[222222];

int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n;
		sum=0;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		for(int i=2;i<=n;i++)
		{
			sum+=a[i]-a[i-1]-1;
		}
		cout<<(sum<3?"YES":"NO")<<endl;
	}
	return 0;
}

CF1692G

题目描述

Given an array aa of length nn and an integer kk , find the number of indices 1 \leq i \leq n - k1≤i≤n−k such that the subarray [a_i, \dots, a_{i+k}][ai​,…,ai+k​] with length k+1k+1 (not with length kk ) has the following property:

  • If you multiply the first element by 2^020 , the second element by 2^121 , ..., and the ( k+1k+1 )-st element by 2^k2k , then this subarray is sorted in strictly increasing order.

More formally, count the number of indices 1 \leq i \leq n - k1≤i≤n−k such that $$2^0 \cdot a_i < 2^1 \cdot a_{i+1} < 2^2 \cdot a_{i+2} < \dots < 2^k \cdot a_{i+k}. $$

输入格式

The first line contains an integer tt ( 1 \leq t \leq 10001≤t≤1000 ) — the number of test cases.

The first line of each test case contains two integers nn , kk ( 3 \leq n \leq 2 \cdot 10^53≤n≤2⋅105 , 1 \leq k < n1≤k<n ) — the length of the array and the number of inequalities.

The second line of each test case contains nn integers a_1, a_2, \dots, a_na1​,a2​,…,an​ ( 1 \leq a_i \leq 10^91≤ai​≤109 ) — the elements of the array.

The sum of nn across all test cases does not exceed 2 \cdot 10^52⋅105 .

输出格式

For each test case, output a single integer — the number of indices satisfying the condition in the statement.

题意翻译

给你一个长度为 n \ (\sum n < 2\cdot 10^5)n (∑n<2⋅105) 的数组 aa,问你在这个数组中,有多少个长度为 k + 1 \ (1\le k < n)k+1 (1≤k<n) 的区间,符合以下的条件:

2^0 \cdot a_i < 2^1 \cdot a_{i + 1} < 2^2 \cdot a_{i + 2} < \dotsi < 2^k \cdot a_{i + k}\\ \footnotesize{注:i 为这个区间开始的位置}20⋅ai​<21⋅ai+1​<22⋅ai+2​<⋯<2k⋅ai+k​注:i为这个区间开始的位置

tzyt翻译

输入输出样例

输入 #1复制

6
4 2
20 22 19 84
5 1
9 5 3 2 1
5 2
9 5 3 2 1
7 2
22 12 16 4 3 22 12
7 3
22 12 16 4 3 22 12
9 3
3 9 12 3 9 12 3 9 12

输出 #1复制

2
3
2
3
1
0

说明/提示

In the first test case, both subarrays satisfy the condition:

  • i=1i=1 : the subarray [a_1,a_2,a_3] = [20,22,19][a1​,a2​,a3​]=[20,22,19] , and 1 \cdot 20 < 2 \cdot 22 < 4 \cdot 191⋅20<2⋅22<4⋅19 .
  • i=2i=2 : the subarray [a_2,a_3,a_4] = [22,19,84][a2​,a3​,a4​]=[22,19,84] , and 1 \cdot 22 < 2 \cdot 19 < 4 \cdot 841⋅22<2⋅19<4⋅84 .

In the second test case, three subarrays satisfy the condition: - i=1i=1 : the subarray [a_1,a_2] = [9,5][a1​,a2​]=[9,5] , and 1 \cdot 9 < 2 \cdot 51⋅9<2⋅5 .

  • i=2i=2 : the subarray [a_2,a_3] = [5,3][a2​,a3​]=[5,3] , and 1 \cdot 5 < 2 \cdot 31⋅5<2⋅3 .
  • i=3i=3 : the subarray [a_3,a_4] = [3,2][a3​,a4​]=[3,2] , and 1 \cdot 3 < 2 \cdot 21⋅3<2⋅2 .
  • i=4i=4 : the subarray [a_4,a_5] = [2,1][a4​,a5​]=[2,1] , but 1 \cdot 2 = 2 \cdot 11⋅2=2⋅1 , so this subarray doesn't satisfy the condition.

题目中所给出的公式,拆开看,即为连续相邻的k个数,连续的两个数满足a[i]<2*a[i+1],利用前缀和算出到第i个数有多少符合条件的相邻的数,若下标相差为k的两个前缀和之差为k,则为一个符合题意的区间。

#include<iostream>
#include<cstring>
using namespace std;

int t,n,ans,a[222222],k,b[222222];

int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		ans=0;
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for(int i=1;i<=n;i++)
			cin>>a[i];
		for(int i=2;i<=n;i++)
			if(a[i-1]<a[i]*2)
				b[i]+=b[i-1]+1;
		for(int i=1;i<=n-k;i++)
			if(b[i+k]-b[i]==k)
				ans++;
		cout<<ans<<endl;
	}
	return 0;
}

CF1370B

题目描述

Ashish has an array aa of consisting of 2n2n positive integers. He wants to compress aa into an array bb of size n-1n−1 . To do this, he first discards exactly 22 (any two) elements from aa . He then performs the following operation until there are no elements left in aa :

  • Remove any two elements from aa and append their sum to bb .

The compressed array bb has to have a special property. The greatest common divisor ( \mathrm{gcd}gcd ) of all its elements should be greater than 11 .

Recall that the \mathrm{gcd}gcd of an array of positive integers is the biggest integer that is a divisor of all integers in the array.

It can be proven that it is always possible to compress array aa into an array bb of size n-1n−1 such that gcd(b_1, b_2..., b_{n-1}) > 1gcd(b1​,b2​...,bn−1​)>1 .

Help Ashish find a way to do so.

输入格式

The first line contains a single integer tt ( 1 \leq t \leq 101≤t≤10 ) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer nn ( 2 \leq n \leq 10002≤n≤1000 ).

The second line of each test case contains 2n2n integers a_1, a_2, \ldots, a_{2n}a1​,a2​,…,a2n​ ( 1 \leq a_i \leq 10001≤ai​≤1000 ) — the elements of the array aa .

输出格式

For each test case, output n-1n−1 lines — the operations performed to compress the array aa to the array bb . The initial discard of the two elements is not an operation, you don't need to output anything about it.

The ii -th line should contain two integers, the indices ( 11 —based) of the two elements from the array aa that are used in the ii -th operation. All 2n-22n−2 indices should be distinct integers from 11 to 2n2n .

You don't need to output two initially discarded elements from aa .

If there are multiple answers, you can find any.

题意翻译

题意简述

有一个数组 aa 其中有 2n2n 个数,把它压缩进数组 bb,bb 的大小是 n-1n−1。

所谓的“压缩”指的是两种操作:

  • 首先舍弃 aa 当中的两个数(你可以任意选择)。
  • 然后每次取出剩下的数组 aa 当中的两个数,把他们的和放入数组 bb 当中。

要求最终 bb 数组中所有数的最大公约数(\gcdgcd)要大于 11,即 \gcd\{b_1,b_2,\ldots,b_{n-1}\}>1gcd{b1​,b2​,…,bn−1​}>1。

请你把你每一次从 aa 中取出的两个数在原来的 aa 中的下标输出,如果答案不唯一输出任意一种即可。

输入输出格式

第一行,一个整数 t(1\leq t\leq 10)t(1≤t≤10),代表数据组数。

对于每一组数据,第一行一个整数 n(1\leq n\leq 1000)n(1≤n≤1000) 意义如题所述。接下来一行共 2n2n 个整数代表数组 aa,其中 1\leq a_i \leq 1000\ (1\leq i \leq 2n)1≤ai​≤1000 (1≤i≤2n)。

对于每一组数据你共需输出 n-1n−1 行,每行两个整数,代表你一次操作所取处的两个数在原数组 aa 中的下标。(数组 aa 中下标编号从 11 开始。)你不需要输出最开始你舍弃了哪两个数。

输入输出样例

输入 #1复制

3
3
1 2 3 4 5 6
2
5 7 9 10
5
1 3 3 4 5 90 100 101 2 3

输出 #1复制

3 6
4 5
3 4
1 9
2 3
4 5
6 10

说明/提示

In the first test case, b = \{3+6, 4+5\} = \{9, 9\}b={3+6,4+5}={9,9} and \mathrm{gcd}(9, 9) = 9gcd(9,9)=9 .

In the second test case, b = \{9+10\} = \{19\}b={9+10}={19} and \mathrm{gcd}(19) = 19gcd(19)=19 .

In the third test case, b = \{1+2, 3+3, 4+5, 90+3\} = \{3, 6, 9, 93\}b={1+2,3+3,4+5,90+3}={3,6,9,93} and \mathrm{gcd}(3, 6, 9, 93) = 3gcd(3,6,9,93)=3 .

看上去很复杂,其实仔细一想,只要gcd()==2即可,那么只需要对a数组按奇偶进行分类即可,若奇偶的数量均为偶数,则随便在奇偶一组中删掉两个,若均为奇数个,则奇偶各删去一个。对于输出的处理,为了避免一个个写if,开一个cnt,cnt>=2*n-2时停止即可。

#include<iostream>
using namespace std;

int t,a[222222],e[222222],o[222222],po,pe,cnt,n;

int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n;
		po=pe=1;
		for(int i=1;i<=n*2;i++)
		{
			cin>>a[i];
			a[i]%2==0?e[pe++]=i:o[po++]=i;
		}
		cnt=0;
		if(--po%2==1&&--pe%2==1)
		{
			po--;
			pe--;
		}
		for(int i=1;i<=po&&cnt<2*n-2;i++,cnt++)
		{
			cout<<o[i]<<" ";
			if(i%2==0)
				cout<<endl;
		}
		for(int i=1;i<=pe&&cnt<2*n-2;i++,cnt++)
		{
			cout<<e[i]<<" ";
			if(i%2==0)
				cout<<endl;
		}
	}
	return 0;
}

CF1610B

题目描述

An array [b_1, b_2, \ldots, b_m][b1​,b2​,…,bm​] is a palindrome, if b_i = b_{m+1-i}bi​=bm+1−i​ for each ii from 11 to mm . Empty array is also a palindrome.

An array is called kalindrome, if the following condition holds:

  • It's possible to select some integer xx and delete some of the elements of the array equal to xx , so that the remaining array (after gluing together the remaining parts) is a palindrome.

Note that you don't have to delete all elements equal to xx , and you don't have to delete at least one element equal to xx .

For example :

  • [1, 2, 1][1,2,1] is kalindrome because you can simply not delete a single element.
  • [3, 1, 2, 3, 1][3,1,2,3,1] is kalindrome because you can choose x = 3x=3 and delete both elements equal to 33 , obtaining array [1, 2, 1][1,2,1] , which is a palindrome.
  • [1, 2, 3][1,2,3] is not kalindrome.

You are given an array [a_1, a_2, \ldots, a_n][a1​,a2​,…,an​] . Determine if aa is kalindrome or not.

输入格式

The first line contains a single integer tt ( 1 \le t \le 10^41≤t≤104 ) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer nn ( 1 \le n \le 2 \cdot 10^51≤n≤2⋅105 ) — the length of the array.

The second line of each test case contains nn integers a_1, a_2, \ldots, a_na1​,a2​,…,an​ ( 1 \le a_i \le n1≤ai​≤n ) — elements of the array.

It's guaranteed that the sum of nn over all test cases won't exceed 2 \cdot 10^52⋅105 .

输出格式

For each test case, print YES if aa is kalindrome and NO otherwise. You can print each letter in any case.

题意翻译

对于长度为 mm 的序列 bb,我们称 bb 是「回文的」,当且仅当对于所有 i\in[1,m]i∈[1,m],都有 b_i=b_{m-i+1}bi​=bm−i+1​。特别的,空序列也是回文的。

对于一个序列,我们称其是「可爱的」,当且仅当且满足如下条件:

  • 存在数 xx,使得删除序列中若干值等于 xx 的元素后,序列是回文的。(删除元素后,剩余元素会并在一起)

需要注意的是,你并不需要删除所有值等于 xx 的元素,并且,你也可以选择不删除任何元素。

例如:

  • [1,2,1][1,2,1] 是可爱的,因为你不需要删除任何一个数,其本身就是回文的。
  • [3,1,2,3,1][3,1,2,3,1] 是可爱的,因为你可以选择 x=3x=3,然后删除所有值等于 33 的元素,将其变为回文的。
  • [1,2,3][1,2,3] 则不是可爱的。

现在蓝给出了一个长度为 nn 的序列 aa,她希望你能帮她确定其是否是可爱的。

本题多组数据,数据组数为 tt,会在输入的开头给出。对于每组数据,如果给出的序列 aa 是可爱的,请输出 YES,否则输出 NO

题目数据满足:1 \leq t \leq 10^41≤t≤104,1 \leq n \leq 2\times10^51≤n≤2×105,1 \leq a_i \leq n1≤ai​≤n,1 \leq \sum n \leq 2\times10^51≤∑n≤2×105。

输入输出样例

输入 #1复制

4
1
1
2
1 2
3
1 2 3
5
1 4 4 1 4

输出 #1复制

YES
YES
NO
YES

说明/提示

In the first test case, array [1][1] is already a palindrome, so it's a kalindrome as well.

In the second test case, we can choose x = 2x=2 , delete the second element, and obtain array [1][1] , which is a palindrome.

In the third test case, it's impossible to obtain a palindrome.

In the fourth test case, you can choose x = 4x=4 and delete the fifth element, obtaining [1, 4, 4, 1][1,4,4,1] . You also can choose x = 1x=1 , delete the first and the fourth elements, and obtain [4, 4, 4][4,4,4] .

直接暴力就可以,对于奇偶数项分别求__gcd,然后看另一组有没有能被整除的。

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

ll t,n,a[222222],ck,d;

int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n;
		ck=1;
		for(int i=1;i<=n;i++)
			cin>>a[i];
		d=a[1];
		for(int i=3;i<=n;i+=2)
			d=__gcd(d,a[i]);
		for(int i=2;i<=n;i+=2)
			if(a[i]%d==0)
				ck=0;
		if(ck)
		{
			cout<<d<<endl;
			continue;
		}
		ck=1;
		d=a[2];
		for(int i=4;i<=n;i+=2)
			d=__gcd(d,a[i]);
		for(int i=1;i<=n;i+=2)
			if(a[i]%d==0)
				ck=0;
		cout<<(ck?d:0)<<endl; 
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值