A
题意:
给你一个正整数x求gcd(x,y)+y的最大值时y的值(1<=y<x)
这个由于数据量比较小所以直接暴力就可以过
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int n,m;
void solve(){
cin>>n;
ll t=0,k=0;
for(int i=1;i<n;i++){
ll x=gcd(i,n)+i;
if(x>k){
k=x;
t=i;
}
}
cout<<t<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
再来分析一下这个题目,因为y<x所以gcd(x,y)等价于gcd(x,x-y),容易知道gcd(x,x-y)<=x-y,所以gcd(x,x-y)+y<=x,又因为相邻两个数的gcd为1,所以当y=x-1时一定满足题目的情况故可以直接输出x-1。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
void solve(){
cin>>n;
cout<<n-1<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
B
题意:
给您两个字符串a,b并且字符串由0,1组成,找到最大的k并且使k满足a的前缀是b的子序列
这道题是一道双指针
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
void solve(){
cin>>n>>m;
string a,b;cin>>a>>b;
ll res=0;
for(int j=0,i=0;i<n;i++){
while(a[i]!=b[j]&&j<m)j++;
if(j>=m)break;
res++;
j++;
}
cout<<res<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
C
题意:
给你一个数组 x2,x3,…,xn。你的任务是找出任意一个数组 a1,…,an ,
其中:1≤ai≤109 代表所有的 1≤i≤n 。xi=aimodai−1代表所有 2≤i≤n 。
并且1≤xi≤500
分析:
对于一组数找出这组数的最大值然后每次将最大值加上xi的值就可以满足
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int q[N],g[N];
int n,m;
void solve(){
cin>>n;
for(int i=2;i<=n;i++)cin>>q[i];
g[1]=501;
for(int i=2;i<=n;i++){
g[i]=q[i]+g[i-1];
}
for(int i=1;i<=n;i++)cout<<g[i]<<' ';
cout<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
D
题意:
它们开始时都选择了排列中的一个起始位置。
对局持续了 k 个回合。棋手同时下棋。在每个回合中,每个棋手都会发生两件事:
如果棋手当前的位置是 x,他的得分就会增加 ax 。
然后棋手要么停留在当前位置 x ,要么从 x 移动到 px 。
在整整 k 个回合后,得分较高的一方即为获胜者。
分析:
在一组数中最多会循环n次当n次循环后就可以确定最大值,然而在每次循环中需要确定一个值与所记录的最值进行比较,至于确定最值maxn=max(maxn,t+(ll)a[b]*(m-i));
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int q[N],g[N],a[N];
int n,m;
void solve(){
int b,s;
cin>>n>>m>>b>>s;
for(int i=1;i<=n;i++)cin>>q[i];
for(int i=1;i<=n;i++)cin>>a[i];
ll res=0,cut=0;
ll t=0,j=0;
for(int i=1;i<=n&&i<=m;i++){
t+=a[b],j+=a[s];
res=max(res,t+(ll)a[b]*(m-i));
cut=max(cut,j+(ll)a[s]*(m-i));
b=q[b];
s=q[s];
}
if(res==cut)cout<<"Draw\n";
else if(res>cut)cout<<"Bodya\n";
else cout<<"Sasha\n";
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
E
题意:
给您一个n×n的网格每个格子的坐标为(x1,y1),(x2,y2),…,(xn,yn)其中 1≤xi≤n和 1≤yi≤n
假设 H 是任意一对单元格之间不同的曼哈顿距离集合。你的任务是最大化 H 的大小。注释中给出了集合及其构造的例子(这个大小指的应该是元素个数的多少)
单元格 (x1,y1) 和 (x2,y2) 之间的曼哈顿距离等于 |x1−x2|+|y1−y2|。
分析:
对于一个n×n的网格两个点之间的距离0<=x<=2*(n-1)如果想要满足这个情况则需要
当如图所示这样选的时一定满足H的最大
由一号点与其他点可以出现偶数(2,4,6,8,10,12)
由二号点与其他点可以出现奇数(1,3,5,7,9,11)
所以这样一定可以出现最大值
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cout<<i<<' '<<(i<=2?1:i)<<'\n';
}
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
作者水平比较低如果有错误可以在评论区指出!!!栓Q