小苯晨跑
思路:直接设置一个变量flag=1,如果有不相等的就是1,然后就是输出YES,否则就是NO
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
int a[200005];
string s;
signed main()
{
cin>>t;
while(t--)
{
int flag=1;
for(int i=1;i<=4;i++)
cin>>a[i];
for(int i=2;i<=4;i++)
{
if(a[i]!=a[i-1])
{
flag=0;
}
}
if(flag==1)
{
cout<<"NO\n";
}
else
{
cout<<"YES\n";
}
}
return 0;
}
小苯过马路
思路:分情况讨论,假如一开始就是红灯,那么变成绿灯后,一定可以通过,所以就是输出k+t
如果是绿灯,如果可以直接通过,即k>=t,那么就是要输出t
否则就是,等完这个,还要再等一个红灯k+x+t
#include<bits/stdc++.h>
using namespace std;
#define int long long
int x,y,k,t;
char c;
signed main()
{
cin>>x>>y>>k>>t;
cin>>c;
if(c=='R')
{
cout<<k+t<<"\n";
}
else
{
if(k<t)
{
cout<<k+x+t<<"\n";
}
else
{
cout<<t<<"\n";
}
}
return 0;
}
小苯的字符串染色
思路:因为不需要找到最小的操作次数,所以只要碰到是黑的就记录就可以了,先输出有多少个黑色方块数,然后再输出,每个位置就好了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
int a[200005];
string s;
void solve()
{
cin>>n;
cin>>s;
s=' '+s;
int cnt=0;
for(int i=1;i<=n;i++)
{
if(s[i]=='1')
{
cnt++;
}
}
cout<<cnt<<"\n";
for(int i=1;i<=n;i++)
{
if(s[i]=='1')
{
cout<<i<<" "<<i<<"\n";
}
}
}
signed main()
{
cin>>t;
while(t--)
{
solve();
}
return 0;
}
小苯的能量项链
思路:通过题意可以发现,我们只能发现最终只能保留两只珠子,因此,当n的个数小于3的时候,就直接输出累计和即可,否则,要统计后缀和,就是去处理a[i],当前面只删除了i-1个数的时候,那么后面去统计的就是maxn[max(i+1,n-(k-i+1))],maxn数组用于统计后缀最大值,因为k可能会大于n,所以导致数组超界,所以要取一个最值
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[500005];
string s;
int sum=0;
int maxn[500005];
//只能保证剩下两颗珠子
void solve()
{
sum=0;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
if(n<3)
{
cout<<sum<<'\n';
return ;
}
for(int i=n;i>=1;i--)
{
maxn[i]=max(maxn[i+1],a[i]);
}
//前缀最大值就是n-1,但是你最多只能遍历到k个
int ans=0;
for(int i=1;i<=min(n-1,k+1);i++)
{
ans=max(ans,a[i]+maxn[max(i+1,n-(k-i+1))]);
}
cout<<ans<<'\n';
}
signed main()
{
cin>>t;
while(t--)
{
solve();
}
return 0;
}
小苯的最短路
思路:我们很明显发现每个点的最短路权值就是1^i,因此我们s可以发现是有规律的,从2开始,每四个可以视为一组,当减去1之后,
取模为1,则输出n+1
取模为2,输出1
取模为3,输出n,
取模为4,输出0
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
void solve()
{
cin>>n;
if(n==1)
{
cout<<0<<"\n";
}
else
{
int flag=n;
n-=1;
if(n%4==0)
{
cout<<0<<"\n";
}
else if(n%4==2)
{
cout<<1<<"\n";
}
else if(n%4==1)
{
cout<<flag+1<<"\n";
}
else
{
cout<<flag<<"\n";
}
}
}
signed main()
{
cin>>t;
while(t--)
solve();
return 0;
}
小苯的优雅好序列
这题做的时间还是比较长的,因为确实难,但是有一个困惑的地方就是为什么不能排序,排序就错了一个点
算了,等待大佬来给我讲解吧,先说我自己推出来的思路
因为我们要确保ai和aj能有整除的关系,大的能够整除所有小的,因此我们可以将ai设置为x,aj设置为y,假如说我们要增加一个因子为c,因此我们可以得到方程式
(y+c)/(x+c)=Z(Z是整数)
化简式子的到(y-x)/(x+c)=(Z-1),因此x和y的差d是(x+c)的倍数 ,因此我们可以考虑遍历最大值和最小值的差的因数,当因数c满足c-minn<=k&&c-minn>0的时候,就可以得到一种结果,但是遍历一遍整个数太大了,因此我们可以只考虑遍历sqrt(c),另一半的因子就是c/i,然后去判断能否让整个数列变成题目要求的,即可,时间复杂度为O(N)
整体时间复杂度为O(NlogN)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n, k;
int a[200005];
int minn;
int maxn;
bool check(int x)
{
if (x - minn > k || x - minn <= 0)
{
return false;
}
int b[n+1];
for(int i=1;i<=n;i++)
b[i]=a[i];
for(int i=1;i<=n;i++)
{
b[i] += x - minn;
}
for (int i = 2; i <= n; i++)
{
if (max(b[i],b[i-1]) % min(b[i],b[i - 1]) != 0)
return false;
}
return true;
}
void solve()
{
cin >> n >> k;
minn=0x3f3f3f3f;
maxn=0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
minn=min(minn,a[i]);
maxn=max(maxn,a[i]);
}
if (maxn-minn==0) {
cout << k << " " << (k * (k + 1)) / 2 << "\n";
return;
}
int d = maxn-minn;
int cnt = 0, sum = 0;
for (int i = 1; i * i <= d; i++) {
if (d % i == 0) {
if (check(i)) {
cnt++;
sum += i - minn;
}
if (i != d / i && check(d / i)) {
cnt++;
sum += (d / i) - minn;
}
}
}
cout << cnt << " " << sum << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t--) {
solve();
}
return 0;
}