Codeforces Round 943 (Div. 3)(A-E)

Codeforces Round 943 (Div. 3)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值