ZUFE OJ 2301 GW I (3)
Description
GW 是ZUFE的神犇,有一天他想到一种神奇的变换,并且将它命名为GW变换
对于一个数字n,该变换后的值GW(n)为,先令X=n
第一步,如果X为个位数,GW(n)=X,否则执行第二步;
第二步,X的奇数位置的数字之和为a,偶数位置的和为b, X=a*b, 执行第一步;
现在我们有T个询问,对于每个询问输入三个整数数l,r,x
对于每个询问请输出在[l,r]这个闭区间里的数经过该变换后为x的数有多少个
Input
第一行是一个T,表示有T组询问(T<=1000)
接下来T行,每行三个整数l,r,x (0<=l<=r<=10000000)
Output
输出T行,每行一个整数,代表着答案。
Sample Input
2
1 10 2
20 25 0
Sample Output
1
2
HINT
第二个样例中满足条件的值分别为20和25
离线操作
#include<cstdio> #include<cstring> #include<cmath> #include<stack> #include<queue> #include<algorithm> using namespace std; int tot[10]; int ans[1000+10]; int T; int GW[10000000+10]; int r[1000],d; struct Quary { bool flag;//flag==0表示是起点 flag==1表示是终点 int t;//第几组的询问 int u; int x;//要询问数字 }Q[2000+10]; bool cmp(const Quary&a,const Quary&b) { if(a.u==b.u) return a.flag<b.flag; return a.u<b.u; } void init() { memset(tot,0,sizeof tot); memset(ans,0,sizeof ans); } int Tra(int x) { d=0; int A=0,B=0; while(x) { r[d]=x%10; x=x/10; d++; } for(int i=0;i<d;i++) { if(i%2==0) A=A+r[i]; else B=B+r[i]; } return A*B; } void F() { for(int i=0;i<=9;i++) GW[i]=i; for(int i=10;i<=10000000;i++) GW[i]=GW[Tra(i)]; } int main() { F(); scanf("%d",&T); init(); int zzt=0; for(int i=1;i<=T;i++) { int L,R,X; scanf("%d%d%d",&L,&R,&X); if(X>9||X<0) {ans[i]=0;continue;} Q[zzt].flag=0; Q[zzt].t=i; Q[zzt].u=L; Q[zzt].x=X; zzt++; Q[zzt].flag=1; Q[zzt].t=i; Q[zzt].u=R; Q[zzt].x=X; zzt++; } sort(Q,Q+zzt,cmp); int now=0; for(int i=0;i<zzt;i++) { if(Q[i].flag==0) { for(int j=now;j<Q[i].u;j++) tot[GW[j]]++; ans[Q[i].t]=tot[Q[i].x]; now=Q[i].u; } else if(Q[i].flag==1) { for(int j=now;j<=Q[i].u;j++) tot[GW[j]]++; ans[Q[i].t]=tot[Q[i].x]-ans[Q[i].t]; now=Q[i].u+1; } } for(int i=1;i<=T;i++) printf("%d\n",ans[i]); return 0; }