CodeForces 70C Lucky Tickets :找到范围最小的区间使1区间找到的a和2区间找到的b使a*b=rev(a)*rev(b)大于等于w个:技巧(尺取)+map
转化成a/rev(a)==rev(b)/b这样就容易做了
先判断大区间有没有到w个,然后开两个map进行尺取
x=n1 y=1
如果当前对数>=w x--,否则y++,中间有涉及到两个map的删减以及在满足情况下更新答案
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<map> 6 using namespace std; 7 #define LL long long 8 map<double,LL>mp1,mp2; 9 LL rev(LL x) 10 { 11 LL ans=0; 12 while (x){ 13 ans=ans*10+x%10; 14 x/=10; 15 } 16 return ans; 17 } 18 int main() 19 { 20 LL maxx,maxy,w,cnt,i,tx,ty,ax,ay; 21 double tmp; 22 scanf("%I64d%I64d%I64d",&maxx,&maxy,&w); 23 cnt=0; 24 for (i=1;i<=maxx;i++) mp1[1.0*i/rev(i)]++; 25 for (i=1;i<=maxy;i++) cnt+=mp1[1.0*rev(i)/i]; 26 if (cnt<w) {printf("-1\n"); return 0; } 27 tx=maxx; ty=1; 28 cnt=mp1[1.0]; mp2[1.0]++; 29 ax=maxx; ay=maxy; 30 while (tx>=1&&ty<=maxy) 31 { 32 if (cnt>=w){ 33 if (tx*ty<ax*ay) ax=tx,ay=ty; 34 tmp=1.0*tx/rev(tx); 35 cnt-=mp2[tmp]; mp1[tmp]--; tx--; 36 } 37 else{ 38 ty++; 39 tmp=1.0*rev(ty)/ty; 40 cnt+=mp1[tmp]; mp2[tmp]++; 41 } 42 } 43 printf("%I64d %I64d\n",ax,ay); 44 return 0; 45 }