【*】POJ-3899(数论很难)(Lucky Numbers——统计)

转载自: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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值