魔术数
题目描述
一个正整数,它的第i个数字是d[i],则 序列(d [1],d[2],d[3],…,d[t])是X
的数字表示(没有前导零)。特别地,d[1]是最高位数字并且d[t]是X的最低位数字。例如,X =
576的数字表示是(5,7,6)。我们说整数X是魔术数,当且仅当: 1、X是某个整数的平方,即对于某个整数Y ,X = Y * Y。
2、对于X 的数字表示(d[1],d[2],d[3],…,d[t]),它满足d[1] < d[2] > d[3] <
d[4]…,依此类推。也就是说,对于每个奇数下标i < t,满足d[i] < d[i+1],并且对于每个偶数下标i <
t,它满足d[i] > d[i+1]。 给定A和B,输出A和B之间有多少魔术数。
输入
多组测试数据。 第一行,一个整数G,表示有G组测试数据。1 <= G <= 10。 每组测试数据格式: 一行,两个整数A和B。 1 <= B<= 10^10。 1 <= A <= B
输出
共G行,每行一个整数。样例输入
Sample Input
3
1 64
50 60
121 121
Sample Output
7
0
1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll u[100002];
ll save[15];
int main()
{
u[100001]=92233720368547758;
for(ll i=1; i<=100000; i++)
u[i]=i*i;
ll t;
scanf("%lld",&t);
while(t--) {
ll tot=0;
ll s,e;
int sw=1;
scanf("%lld%lld",&s,&e);
ll bs,be;
for(ll i=0; i<=100001; i++)
if(u[i]>s) {
bs=i-1;
break;
}
for(ll i=0; i<=100001; i++)
if(u[i]>e) {
be=i-1;
break;
}
for(ll i=bs; i<=be; i++) {
if(u[i]<s||u[i]>e)
continue;
ll ji=0;
ll temp=u[i];
while(temp) {
save[ji++]=temp%10;
temp/=10;
}
if(ji%2) {
save[ji]=100;
for(ll i=0; i<ji; i++) {
if(i%2) {
if(save[i]<=save[i+1]) {
sw=0;
break;
}
} else {
if(save[i]>=save[i+1]) {
sw=0;
break;
}
}
}
} else {
save[ji]=100;
for(ll i=0; i<ji; i++) {
{
if(i%2) {
if(save[i]>=save[i+1]) {
sw=0;
break;
}
} else {
if(save[i]<=save[i+1]) {
sw=0;
break;
}
}
}
}
}
if(sw)
tot++;
sw=1;
}
printf("%lld\n",tot);
}
}
坑点:1要学会优化,不然会超时。2数据类型,不要用int。
如果把筛子再完善一点点,把魔术数的第二个性质直接筛出来,以后的多组输入就会更节省时间
By-轮月