cf #818 Div.2(A~C)

本文档涵盖三个Codeforces竞赛题目:A.Madoka的奇思妙想(lcm与gcd的应用),B.棋盘上的相遇(坐标对角线布局),C.Madoka与形式陈述(数组操作优化)。通过实例解析展示了不同场景下的算法设计和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cf #818 Div.2

A. Madoka and Strange Thoughts

  • 题意

    • 问1~n中有多少对(a,b)满足lcm(a,b)<=3*gcd(a,b)
  • 题解

    • 已知lcm(a,b)=a*b/gcd(a,b),所以原式可以化为,并且只有如下几种情况符合要求,下列式子中认为a,b等价,但是题目中非等价,简写
      a × b g c d 2 ( a , b ) < = 3 设 g c d ( a , b ) = t ; 1. a = b = t 2. a = t , b = 2 t 3. a = t , b = 3 t \frac{a\times b}{gcd^2(a,b)}<=3\\ 设gcd(a,b)=t;\\ 1.a=b=t\\ 2.a=t,b=2t\\ 3.a=t,b=3t gcd2(a,b)a×b<=3gcd(a,b)=t;1.a=b=t2.a=t,b=2t3.a=t,b=3t

    • 因此1~n中,有n对a=b的,有n/2对a=t,b=2t的,有n/3对a=t,b=2t的。同时a,b位置可以互换

  • 代码

#include <iostream>

using namespace std;
int n;

void solve() {
    cin>>n;
    cout<<n+(n/2+n/3)*2<<'\n';
}

int main() {
    int t;
    cin>>t;
    while(t--) solve();
    
    return 0;
}

B. Meeting on the Line

  • 题意

    • 有n阶的棋盘,n为k的倍数,构造一个每k个行或者列的格子都至少有一个’X’的其他都为’.‘的棋盘。给定一个位置(r,c)放置’X’,输出一个’X’最少的棋盘情况
  • 题解

    • 棋盘放的最少的个数是确定的,每一行都需要放置n/k个’X’,所以总共要放置n*n/k个’X’
    • 对于一个k*k的小棋盘,在副对角线上放置’X’为一种构造方式,放在副对角线还有一个好处,就是副对角线上的横纵坐标之和恒定,方便计算和构造
    • 对于n*n的棋盘,在给定点所在的副对角线放上’X’之后,还需要上下左右平移k个位置后得到的对角线放上’X’,即对所有的坐标(i,j)若满足**(i+j)%k==(r+c)%k**则放置’X’,否则放置’.',易证得其位置一定符合要求且’X’数量为最小
  • 代码

#include <iostream>
#include <cmath>

using namespace std;

void solve() {
    int n,k,r,c;
    cin>>n>>k>>r>>c;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            if(abs(i+j-r-c)%k==0) cout<<'X';
            else cout<<'.';
        }
        puts("");
    }
}

int main() {
    int t;
    cin>>t;
    while(t--) solve();
    
    return 0;
}

C. Madoka and Formal Statement

  • 题意

    • 给定两个长度为n的数组a,b,经过若干操作,问能否将a变成b
    • 操作:若a[i]<=a[(i+1)%n],则a[i]++
  • 题解

    • 对于a[i]!=b[i]时,若a[i]>b[i],则不可能完成变换;若a[i]<b[i],要将a[i]变成b[i],需要保证b[i+1]+1>=b[i],因为一定能找到一种贪心方法,将a[i+1]变成b[i]-1
  • 代码

#include <iostream>

using namespace std;
const int N=2e5+10;

int n,a[N],b[N];

void solve() {
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++) cin>>b[i];
    for(int i=0;i<n;i++)
      //不合法的情况
        if( a[i]>b[i] || (a[i]!=b[i] && b[i]>b[(i+1)%n]+1) ) {
            puts("NO");
            return ;
        }
    
    puts("YES");
}

int main() {
    int t;
    cin>>t;
    while(t--) solve();
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值