洛谷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与a2的差
证明:
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;
}
这样时间上就大大的节约了!