洛谷P1348 Couple number

洛谷P1348 Couple number

emmm很容易去想用暴力去解题啊……但是看上去这题正解就不是暴力了~

首先要明确平方差公式这一存在

a^2-b^2=(a+b)(a-b)

二话不说打个表看看规律

#include<cstdio>
using namespace std;
int main(){
    freopen("in.txt","w",stdout);
    for(int i=0;i<20;i++){
        for(int j=i;j<20;j++)
            printf("%d ",j*j-i*i); 
        puts("");
    }
    
    return 0;
}
0 1  4  9  16  25  36  49  64  81  100 121 144 169 196 225 256 289 324 361 
0 3  8  15 24  35  48  63  80  99  120 143 168 195 224 255 288 323 360 
0 5  12 21 32  45  60  77  96  117 140 165 192 221 252 285 320 357 
0 7  16 27 40  55  72  91  112 135 160 187 216 247 280 315 352 
0 9  20 33 48  65  84  105 128 153 180 209 240 273 308 345 
0 11 24 39 56  75  96  119 144 171 200 231 264 299 336 
0 13 28 45 64  85  108 133 160 189 220 253 288 325 
0 15 32 51 72  95  120 147 176 207 240 275 312 
0 17 36 57 80  105 132 161 192 225 260 297 
0 19 40 63 88  115 144 175 208 243 280 
0 21 44 69 96  125 156 189 224 261 
0 23 48 75 104 135 168 203 240 
0 25 52 81 112 145 180 217 
0 27 56 87 120 155 192 
0 29 60 93 128 165 
0 31 64 99 136 
0 33 68 105 
0 35 72 
0 37 
0 

从第一列可以看出0是一个CP数;

证明:
    N=a^2-b^2
    当a=b时a^2=b^2
    所以N=0

从第二列可以看出数由1开始递增,而且是所有的奇数

又这列都是由(a+1)^2与a^2的差

证明:
    N=a^2-b^2
    当a=b+1时
    N=(b+1)^2-b^2=b^+2b+1-b^=2b+1
    当b为任意非负数时,N可以为任意奇数
证明2:
    (a+b)(a-b)=N
    (a+b)与(a-b)的奇偶性一致
    所以(a+b)和(a-b)都是奇数时
    他们的积也一定是奇数!

然后第三列全是偶数,而且都是4的倍数,其他非奇数列都满足是4的倍数这一性质,于是猜想:CP数是奇数+4的倍数

为了证明所有CP数中的非奇数(也就是偶数)全是4的倍数

于是写了程序用来验证

#include<cstdio>
using namespace std;
int main(){
    freopen("in.txt","r",stdin);
    for(int i=1;i<=10000;i++){
        if(i%2==0){
            if(i%4!=0){
                puts("NO");
                return 0;
            }
        }
    }
    puts("YES");
    return 0;
}

程序最后输出YES

证明:
    (a+b)(a-b)=N
    (a+b)与(a-b)的奇偶性一致
    所以当(a+b)与(a-b)都是偶数时
    (a+b)和(a-b)都是2的倍数
    所以两数相乘必有2*2=4
    所以两数会被4整除

证出CP数的性质后就可以上代码了!

#include<cstdio>
using namespace std;
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    int ans=0;
    for(int i=a;i<=b;i++){
        if(i&1==1)ans++;
        else{
            if(i%4==0)ans++; 
        } 
    }
    printf("%d",ans);
    return 0;
}

这里是枚举了这个给定范围的所有数,然后判断是否是奇数或者4的倍数

虽然这份代码能AC这道题

但是如果数据范围一大1e9那种级别的

岂不是很尴尬~~~

所以有没有公式能直接算出来呢??

#include<cstdio>
using namespace std;
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    int c=a,d=b;
    int ans=0;
    if(a%2==0)a++;
    if(b%2==0)b--;
    if(a<=b)ans=(b-a)/2+1;
    while(c%4!=0)c++;
    while(d%4!=0)d--;
    if(c<=d)ans+=(d-c)/4+1;
    printf("%d",ans);
    return 0;
}

这样时间上就大大的节约了!

转载于:https://www.cnblogs.com/Neworld2002/p/8470848.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值