A - Era
题意:
给定一个数组,要求数组任意一个元素a[i]都要满足a[i]<=i这个条件,你可以执行的操作就是往数组中任意位置插入元素,问最少需要插入多少个元素才能创造出题目要求的数组呢?
做法:
要求数组每一个元素都得小于等于它的下标位置,问插入的最少的个数,直接找数组里和下标位置差距最大的数不就哦了?这样直接保证了左右两边的数据的合理性!这不直接开冲?OMO
#include<bits/stdc++.h>
#define int long long
typedef long long ll;
using namespace std;
const int mod=1e9+7;
const int maxn=2e5+10;
int q,n,a;
signed main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
int ans=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a;
ans=max(ans,a-i);
}
cout<<ans<<endl;
}
return 0;
}
B - XOR Specia-LIS-t
题意:
给了一个数组,要求你把数组分成任意个子数组(连续的部分数组),然后每个子数组中最长上升子序列(后续解释)的长度就是这个子数组的值,然后需要保证这几个子数组的值进行异或运算后得到的值为0,询问是否可以达成这种操作?
做法:
看到异或加最长上升子序列的内心独白:???这什么东西,是我这种蒟蒻能做的吗?然后去找了一下异或的特性
异或(相同为0,不同为1)
1^1=0
1^0=1
0^1=1
0^0=0
某个数字与0异或的结果就是自己;与自身异或的结果为0
SO!!如果你要做到这个数据异或为0的话,那么你得保证你划分的数组都是一个数字(或者你做到每个数组的值正好是互补的样子)显然看来前者比较好实现,其次声明一个数字也算是上升子序列,这个的值为1。所以我们其实可以就把数组拆成一个一个的数据,这样保证了每一个子数组的值都是1。这样我们需要考虑的地方就只有一个了:数组长度。长度无非两种情况:1、偶数,完全没问题,直接一个个划分。2、奇数,有点问题,把其中两个数组当成一个来看,也就是说你得满足一个条件即:a[i]>a[i+1]。把这两个数据放在一起值依旧为1,否则的话就无法满足条件了。
#include<bits/stdc++.h>
#define int long long
typedef long long ll;
using namespace std;
const int mod=1e9+7;
const int maxn=2e5+10;
int n,a[maxn];
signed main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
cin>>n;
/*int ans=1;
for(int i=2;i<=n;i++)
ans=ans^i;
cout<<ans<<endl;*/
for(int i=1;i<=n;i++)
cin>>a[i];
if(n%2==0)
cout<<"YES"<<endl;
else
{
int flag=0;
for(int i=1;i<n;i++)
{
if(a[i]>=a[i+1])
{
flag=1;
break;
}
}
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
return 0;
}
C - Di-visible Confusion
题意:
依旧是熟悉的一个数组,数组里的任意数据a[i],若a[i]无法整除(i+1)(也就是a[i]%(i+1)!=0)问数组里的数据是否全部都可以消去呢?注意:当数组中前面的数据消去时,下一次操作时后面的数据是会向前移动的
做法:
这个不能想复杂了,容易给自己绕到头皮发麻。试想一下,这某一个数据a[i],假设他前面的数据一定都是能消掉的(也就是满足题目条件)那么轮到a[i]的时候那是不是有2,3,4,5,……,i-1个数据呢?这其中只要有一个满足不被a[i]整除,那么这个数据就是合法的,相反的如果全都能被整除,那么这个数据永远无法消掉,也就是该数组不合法!
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
int t,n;
cin>>t;
while(t--)
{
bool flag;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
flag=false;
for(int j=2;j<=i+1;j++)
{
if(a[i]%j!=0)
{
flag=true;
break;
}
}
if(!flag)
{
break;
}
}
if(!flag)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}
D - Moderate Modular Mode
题意:
纯纯的土匪题目!!问给定数字x,y,需要确定一个数字n,满足n mod x = y mod n (n对于x的余数与y对于n的余数,也就是n%x==y%n)问数字n为多少?
做法:
两个数字x,y,无非只有三种情况:1、x == y,这是最简单的,直接输出x就行,因为都是一个数字,余数都为0。2、x>y,最直观的感觉x+y,(x+y) % x = x and y % (x+y) = y 。3、x<y,最难看明白的一种情况:
当 y%x==0 时,x就满足条件。
假设 n<x,n%x ==n,y%n <n,因此不成立
假设n>y,n%x <=x,y%n ==y,因此也不成立
所以n只能在x,y之间,下面以图来说明:
如图示,P就是n的最佳位置,求解方法有两种:y-(y%x)/2 OR ((y/x)*x+y)/2。任取其一即可!
不太理解的童鞋,请移步刘队博客
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
int t,n;
cin>>t;
while(t--)
{
int x,y;
cin>>x>>y;
if(x==y)
{
cout<<x<<endl;
}
else if(x>y)
{
cout<<x+y<<endl;
}
else
{
if(y%x==0)
cout<<x<<endl;
else
cout<<(ll)((y/x)*x+y)/2<<endl;
}
}
return 0;
}
/**
x>y 15 5
n=5
*/
今日小结
快快乐乐的一天从A题开始,算了吧,我没那觉悟。正常刷题正常写题解,做到问心无愧吧!