2023年蓝桥杯省赛c/c++A组c题—平方差,d题—更小的数

文章讨论了如何计算满足平方差关系的整数数量,并提供了解决特定数学问题的方法。同时,介绍了如何计算一个数字字符串中满足条件的不同子串反转方案。
摘要由CSDN通过智能技术生成

平方差

题目描述

给定 L,R,问 L≤x≤R 中有多少个数 x 满足存在整数y,z 使得 x=y2−z2。

输入格式

输入一行包含两个整数 L,R,用一个空格分隔。

输出格式

输出一行包含一个整数满足题目给定条件的 x 的数量。

输入输出样例

输入 #1

1 5

输出 #1

4

说明/提示

【样例说明】
  • 1=1的平方−0的平方
  • 3=2的平方−1的平方
  • 4=2的平方−0的平方
  • 5=3的平方−2的平方
【评测用例规模与约定】

对于 40% 的评测用例,L,R≤5000;

对于所有评测用例,1≤L≤R≤10的9次幂。

我们可以将x=y^2-z^2写成x=(y+z)*(y-z),有一个数学结论是奇数加减偶数=奇数,偶数加减偶数=偶数,奇数加减奇数=偶数,奇数*奇数=奇数*偶数加上奇数=奇数,偶数*偶数(可以将y-z=2c1,y+z=2c2,相乘得到4c1c2)是4的倍数,所以我们的答案是奇数或者是4的倍数,推导第一个就是x^2-(x-1)^2=2*x-1,通过这个可以得到任意位置上的奇数,x>=1,x为正整数,所以我们可以得到第一个结论:所有的奇数都可以被两个平方数表示。推导第二个就是x^2-(x-2)^2=4*(x-1)。所以这道题答案可以写成一个式子:x/2上取整+x/4。

#include<bits/stdc++.h>
using namespace std;
int calc(int x)
{
    return (x+1)/2+x/4;
}
int main()
{
    int l,r;
    cin>>l>>r;
    cout<<calc(r)-calc(l-1)<<endl;
    return 0;
}

 更小的数

image

小蓝有一个长度均为 n 且仅由数字字符 0∼9 组成的字符串,下标从 0到 n−1,你可以将其视作是一个具有 n 位的十进制数字 num,小蓝可以从num 中选出一段连续的子串并将子串进行反转,最多反转一次。小蓝想要将选出的子串进行反转后再放入原位置处得到的新的数字 numnew​ 满足条件 numnew​<num,请你帮他计算下一共有多少种不同的子串选择方案,只要两个子串在num 中的位置不完全相同我们就视作是不同的方案。

注意,我们允许前导零的存在,即数字的最高位可以是 0,这是合法的。

输入格式

输入一行包含一个长度为 n 的字符串表示num(仅包含数字字符 0∼9),从左至右下标依次为 0∼n−1。

输出格式

输出一行包含一个整数表示答案。

输入输出样例

输入 #1

210102

输出 #1

8

说明/提示

【样例说明】

一共有 8 种不同的方案:

  1. 所选择的子串下标为 0∼1,反转后的 numnew​=120102<210102;
  2. 所选择的子串下标为 0∼2,反转后的 numnew​=012102<210102;
  3. 所选择的子串下标为0∼3,反转后的 numnew​=101202<210102;
  4. 所选择的子串下标为0∼4,反转后的 numnew​=010122<210102;
  5. 所选择的子串下标为0∼5,反转后的 numnew​=201012<210102;
  6. 所选择的子串下标为1∼2,反转后的numnew​=201102<210102;
  7. 所选择的子串下标为 1∼4,反转后的 numnew​=201012<210102;
  8. 所选择的子串下标为 3∼4,反转后的 numnew​=210012<210102。
【评测用例规模与约定】

对于 20% 的评测用例,1≤n≤100;

对于40% 的评测用例,1≤n≤1000;

对于所有评测用例,1≤n≤5000。

#include<bits/stdc++.h>
using namespace std;
string s;
int main()
{
    cin>>s;
    int n=s.size(),ans=0;
    for(int i=0;i<n;i++){
        //子串长度为偶数
        bool could_reverse=0;
        for(int l=i-1,r=i;0<=l&&r<n;l--,r++){
            if(s[l]>s[r]) could_reverse=1;
            if(s[l]<s[r]) could_reverse=0;
            ans+=could_reverse;
        }
        //子串长度为奇数
        could_reverse=0;
        for(int l=i-1,r=i+1;0<=l&&r<n;l--,r++){
            if(s[l]>s[r]) could_reverse=1;
            if(s[l]<s[r]) could_reverse=0;
            ans+=could_reverse;
        }
    }
    cout<<ans;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值