【2020CF Round #627 (Div. 3)】A,B,C,D题(E,F题更新中...)
You are given some Tetris field consisting of nn columns. The initial height of the ii-th column of the field is aiai blocks. On top of these columns you can place only figures of size 2×1 (i.e. the height of this figure is 2 blocks and the width of this figure is 1 block). Note that you cannot rotate these figures.
Your task is to say if you can clear the whole field by placing such figures.
More formally, the problem can be described like this:
The following process occurs while **at least one ai is greater than 0:
- You place one figure 2×1 (choose some \(i\) from 1 to n and replace ai with \(a_i\)+2);
- then, while all aiai are greater than zero, replace each aiai with \(a_i\)−1.
And your task is to determine if it is possible to clear the whole field (i.e. finish the described process), choosing the places for new figures properly.
You have to answer tt independent test cases.
Input
The first line of the input contains one integer tt (1≤t≤100) — the number of test cases.
The next 2t lines describe test cases. The first line of the test case contains one integer nn (1≤n≤100) — the number of columns in the Tetris field. The second line of the test case contains nn integers \(a_1,a_2,…,a_n (1≤a_i≤100)\), where \(a_i\)is the initial height of the $i-th $column of the Tetris field.
Output
For each test case, print the answer — "YES" (without quotes) if you can clear the whole Tetris field and "NO" otherwise.
Example
input
4
3
1 1 3
4
1 1 2 1
2
11 11
1
100
output
YES
NO
YES
YES
【题目大意】:有n个俄罗斯方块(其实都是宽为1,高度为\(a_i\) 的长条形),现在有若干个宽为1,高为2的方块可以放置,问你是否可以把整个俄罗斯方块消掉?
【思路分析】:整体来说看懂了就是打卡题。首先有两个操作:
1.可以在任意位置i放置1x2的方块,把\(a_i\)的高度加2
2.当所有的\(a_i\)高度都大于0,那么就让所有的\(a_i\)减1(类似于俄罗斯方块的消除操作)
用样例自己简单的推一下,特别是答案是“YES”和”NO“的各试一下。不难发现如下的规律:“由于加的是一个2,是偶数,不会改变原来数字的奇偶性。要想所有的都消掉,初始序列里面奇偶性应该是一致才能保证消掉。”所以我们只需要判断一下,所有数字的奇偶性是不是一致的就可以了。
【参考代码】
#include <bits/stdc++.h>
using namespace std;
const int N = 2*1e5+9;
int a[N];
int n;
int main()
{
int t;
cin>>t;
while(t--){
int flag=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=2;i<=n;i++){
if(a[i]%2!=a[1]%2){ //以第一个数奇偶性为基准,判断所有的数的奇偶性
flag=0;
break;
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
You are given an array \(a\) consisting of \(n\) integers.
Your task is to determine if aa has some subsequence of length at least 3 that is \(a\) palindrome.
Recall that an array \(b\) is called a subsequence of the array \(a\) if \(b\) can be obtained by removing some (possibly, zero) elements from \(a\) (not necessarily consecutive) without changing the order of remaining elements. For example, [2][2], [1,2,1,3][1,2,1,3] and [2,3][2,3] are subsequences of [1,2,1,3][1,2,1,3], but [1,1,2][1,1,2] and [4][4] are not.
Also, recall that \(a\) palindrome is an array that reads the same backward as forward. In other words, the array \(a\) of length \(n\) is the palindrome if \(a_i=a_{n−i−1}\) for all \(i\) from 1 to n. For example, arrays [1234][1234], [1,2,1][1,2,1], [1,3,2,2,3,1][1,3,2,2,3,1] and [10,100,10][10,100,10] are palindromes, but arrays [1,2][1,2] and [1,2,3,1][1,2,3,1] are not.
You have to answer \(t\) independent test cases.
Input
The first line of the input contains one integer \(t(1≤t≤100)\) — the number of test cases.
Next 2t lines describe test cases. The first line of the test case contains one integer \(n (3≤n≤5000)\) — the length of \(a\). The second line of the test case contains nn integers \(a_1,a_2,…,a_n(1≤a_i≤n)\), where aiai is the ii-th element of \(a\).
It is guaranteed that the sum of nn over all test cases does not exceed 5000 (∑n≤5000).
Output
For each test case, print the answer — "YES" (without quotes) if aa has some subsequence of length at least 33 that is a palindrome and "NO" otherwise.
Example
input
5
3
1 2 1
5
1 2 2 3 2
3
1 1 2
4
1 2 2 1
10
1 1 2 2 3 3 4 4 5 5
output
YES
YES
NO
YES
NO
【题目大意】:给定一个数列a,b是数列a的子串,b可以通过删去a的数字得到,但不能改变位置。问是否存在一个长度至少大于3的回文子串b?
【思路分析】:关键在这个至少大于3,回文串就是前后相同,假设有一对相同,那么长度已经等于2了。我们再随便选一个数字,放在中间就能满足至少大于3的要求了。
那么就可以遍历数组\(a\)查找是否存在一对相同的元素,并且他们间距应该大于2。
【参考代码】
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+9;
int a[N];
int n;
int main()
{
int t ;
cin>>t;
while(t--){
scanf("%d",&n);
int flag=0; //假设不存在
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n-2;i++){ //注意遍历的范围,保证了间隔的距离
for(int j=n;j>=i+2;j--){
if(a[i]==a[j]){ //如果存在一对
flag=1;
cout<<"YES"<<endl;
break; //结束内层循环
}
}
if(flag) break; //这个是为了结束外层循环
}
if(!flag) cout<<"NO"<<endl;
}
return 0;
}
There is a frog staying to the left of the string \(s=s_1s_2…s_n\)consisting of \(n\) characters (to be more precise, the frog initially stays at the cell 0). Each character of \(s\) is either 'L' or 'R'. It means that if the frog is staying at the \(i-th\)cell and the \(i-th\) character is 'L', the frog can jump only to the left. If the frog is staying at the \(i-th\) cell and the \(i-th\) character is 'R', the frog can jump only to the right. The frog can jump only to the right from the cell 0.
Note that the frog can jump into the same cell twice and can perform as many jumps as it needs.
The frog wants to reach the \(n+1-th\) cell. The frog chooses some positive integer value dd before the first jump (and cannot change it later) and jumps by no more than dd cells at once. I.e. if the ii-th character is 'L' then the frog can jump to any cell in a range [max(0,i−d);i−1][max(0,i−d);i−1], and if the \(i-th\) character is 'R' then the frog can jump to any cell in a range [i+1;min(n+1;i+d)][i+1;min(n+1;i+d)].
The frog doesn't want to jump far, so your task is to find the minimum possible value of \(d\) such that the frog can reach the cell \(n+1\) from the cell 0 if it can jump by no more than dd cells at once. It is guaranteed that it is always possible to reach n+1 from 0.
You have to answer \(t\) independent test cases.
Input
The first line of the input contains one integer \(t (1≤t≤10^4)\) — the number of test cases.
The next tt lines describe test cases. The ii-th test case is described as a string ss consisting of at least 1 and at most \(2⋅10^5\) characters 'L' and 'R'.
It is guaranteed that the sum of lengths of strings over all test cases does not exceed \(2⋅10^5(∑|s|≤2⋅10^5).\)
Output
For each test case, print the answer — the minimum possible value of \(d\) such that the frog can reach the cell \(n+1\) from the cell 0 if it jumps by no more than \(d\) at once.
Example
input
6
LRLRRLL
L
LLR
RRRR
LLLLLL
R
output
3
2
3
1
7
1
【题目大意】:有一个青蛙要从0跳到n+1的位置,在每个位置有一个L或R,代表青蛙下一次跳的方向。起始确定一个d,每次青蛙可以跳小于等于d的距离,求问这个最小的d。
【思路分析】:这道题可以先模拟一下样例,看看青蛙是如何跳跃的。在分析的过程中,其实可以发现我们的总目标是向右跳,向左跳的操作其实都可以被向右跳的操作抵消。那可能就有了如下的猜想:
1.问题的答案可能与L和R的数量有关
2.问题的答案可能与L和R的位置相关
最终反复检验、验证了过后,发现问题的答案与R的位置有关。因为青蛙想要往右边跳,那我们d就尽可能能让它从一个R跳到另一个R去,所以问题的答案就是R与R之间最长的间隔距离。
以第4个样例LLLLLL为例,没有R怎么办,其实可以把起始点和目标点都看作是R,序列就成了RLLLLLLR,上面这个算法就成立了。
【参考代码】
#include <bits/stdc++.h>
using namespace std;
const int N = 2*1e5+9;
int n;
char a[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%s",a);
int len=strlen(a);
int maxn=0,t=-1,t1=0;
for(int j=0;j<len;j++)
{
if(a[j]=='R')
{
maxn=max(j-t,maxn); //更新最长距离
t=j; //保存当前R的位置
}
}
maxn=max(maxn,len-t);
cout<<maxn<<endl;
}
return 0;
}
The next lecture in a high school requires two topics to be discussed. The \(i-th\) topic is interesting by \(a_i\) units for the teacher and by \(b_i\) units for the students.
The pair of topics \(i\) and$ j (i<j)$ is called good if \(a_i+a_j>b_i+b_j\) (i.e. it is more interesting for the teacher).
Your task is to find the number of good pairs of topics.
Input
The first line of the input contains one integer \(n\) (\(2≤n≤2⋅10^5\)) — the number of topics.
The second line of the input contains nn integers \(a_1,a_2,…,a_n\)(\(1≤a_i≤10^9\)), where \(a_i\) is the interestingness of the \(i-th\) topic for the teacher.
The third line of the input contains \(n\) integers \(b_1,b_2,…,b_n\) \((1≤b_i≤10^9),\) where \(b_i\) is the interestingness of the \(i-th\) topic for the students.
Output
Print one integer — the number of good pairs of topic.
Examples
input
5
4 8 2 6 2
4 5 4 1 3
output
7
input
4
1 3 2 4
1 3 2 4
output
0
【题目大意】:给出一个a序列和b序列,求问a序列中多少对\(a_i+a_j>b_i+b_j (i<j)\)?
【思路分析】:把\(a_i+a_j>b_i+b_j\)变一下形,\((a_i-b_i)+(a_j-b_j)>0\)。我们预处理一个数组d,代表a和b之间的差值,那么式子就变成了\(d_i+d_j>0\)。
所以问题就变成了:问数组d里面有多少对数两两相加大于0?,如果用枚举,时间复杂度是\(O(N^2)\),而题目里$N \leq 2 \times 10^5 $,这样的时间复杂度肯定会超时的。
所以我们不能这么暴力的求解,得想一些方法来处理一下这个\(d\)数组,让我们快速的求解。
很容易想到的就是对\(d\)进行一下排序,这里正数从小到排,负数(绝对值)从大到小排,恰好就是对\(d\)从小到大排序。这样有什么好处呢?我们可以从正数取一个\(x\),负数取一个\(y\),如果\(x+y>0\),那么\(y\)后面的数肯定就大于0,那我们直接计算就可以得到,就省下了时间。
这里的话,for遍历正数\(x\),然后用二分查找去找\(y\),使得\(x+y\)恰好大于0。所以整体的时间复杂度是\(O(N \log N)\),能够通过这道题。
【参考代码】
#include <bits/stdc++.h>
using namespace std;
const int N = 2*1e5+9;
int a[N],b[N],d[N];
int n,maxn,len1,len2;
int cmp(int x,int y){
return x>y;
}
int main()
{
long long cnt,t ;
scanf("%d",&n);
cnt=0;
len1=len2=0;
int flag=1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) {
scanf("%d",&b[i]);
d[i]=a[i]-b[i]; //存a,b的差值
}
sort(d+1,d+n+1);
for(int i=1;i<n;i++){
int l=i+1,r=n+1;
while(l<r){ //找恰好x+y>0的位置
int mid=(l+r)>>1;
if(d[mid]+d[i]>0) r=mid;
else l=mid+1;
}
if(r!=n+1) cnt+=(n-r+1);
}
cout<<cnt;
return 0;
}
E、F后续放出...

浙公网安备 33010602011771号