转载自:http://hi.baidu.com/billdu/item/c6dda7310196a9f6a8842830
代码如下:
char A[50], B[50];
/* 求[1, upper]中后last_length位是last的Lucky Number总数 */
ll stat_n(char *upper, char* last, int last_length)
{
ll res = 0; bool minus = false;
int len = strlen(upper), i;
for (i = 0; i < last_length; i++) {
int tt = i + len - last_length;
if (upper[tt] > last[i]) break;
else if (upper[tt] < last[i]) { minus = true; break; }
}
if (last_length == 0) for (i = 1; i < len; i++) res += (ll)1 << i;
int m = len - last_length;
for (i = 0; i < m; i++) {
if (upper[i] < '4') break;
else if (upper[i] > '4' && upper[i] < '7') { res += (ll)1 << (m - i - 1); break; }
else if (upper[i] == '7') res += (ll)1 << (m - i - 1);
else if (upper[i] > '7') { res += (ll)1 << (m - i); break; }
}
if (i == m && minus == false && (m == 0 || upper[m - 1] == '4' || upper[m - 1] == '7')) ++res;
return res;
}
/* 求[1, upper]中反转会超出performer范围的Lucky Number总数 */
ll stat_m (char *upper, char *performer)
{
ll res = 0;
char mem[50], *last = &mem[49];
int len = strlen(upper);
for (int i = 0; i < len; i++) {
if (performer[i] > '7') break;
else if (performer[i] == '7') { *(last--) = '7'; }
else if (performer[i] > '4' && performer[i] < '7') {
*last = '7';
res += stat_n(upper, last, i + 1); break;
} else if (performer[i] == '4') { *last = '7'; res += stat_n(upper, last, i + 1); *(last--) = '4'; }
else if (performer[i] < '4') {
*last = '7';
res += stat_n(upper, last, i + 1);
*last = '4';
res += stat_n(upper, last, i + 1); break;
}
}
return res;
}
int main ()
{
int T;
scanf("%d", &T);
while (T--) {
scanf("%s %s", A, B);
int len = strlen(A);
if (A[len - 1] != '0') --A[len - 1];
ll n = stat_n(B, NULL, 0) - stat_n(A, NULL, 0);
ll m = stat_m(B, B) + stat_m(A, A);
if (len == strlen(B)) m -= stat_m(A, B) * 2;
printf("%lld\n", n + m);
}
return 0;
}