枚举--hdu5936 difference

Little Ruins is playing a number game, first he chooses two positive integers  y  and  K  and calculates  f(y,K) , here

f(y,K)=z in every digits of yzK(f(233,2)=22+32+32=22)


then he gets the result

x=f(y,K)y


As Ruins is forgetful, a few seconds later, he only remembers  K x  and forgets  y . please help him find how many  y  satisfy  x=f(y,K)y .
 

Input
First line contains an integer  T , which indicates the number of test cases.

Every test case contains one line with two integers  x K .

Limits
1T100
0x109
1K9
 

//即求0 <= x <= 1e9时有多少个y满足x + y == f(y,k)

//1 <= k <= 9,f(y,k)min = f(y,1) < ..< f(y,i) < ... < f(y,k)max = f(y,9) f(y,k)关于k是递增函数

//y1位时,可以知道y == f(y,1) < f(y,i) 此时x0即可

//y2位时,f(y,k)min < y < f(y,k)max,存在正整数x使得等式x + y == f(y,k)成立

//假设ym位时不存在正整数x使等式成立,f(y,k)max < 10^(m - 1) <= y <= x + y

//f(y,k)max <= m * 9^9 < 10 ^(m - 1)成立,m = 9时还不成立,m >= 10时不等式恒成立,不等式成立即y10位时,不存在正整数x使得x + y == f(y,k)

//所以y最多有10位数字

//啊啊啊啊啊啊x==0的时候,y = 0也满足,要减掉1

#include <iostream>

#include <cstdio>

#include <cmath>

#include <map>

using namespace std;

typedef long long ll;

ll ak[10][10];//ak次方

map<ll,ll> cnt[10];

void init_ak()

{

    for (int i = 0; i < 10; i ++) {

        for (int j = 1; j < 10; j ++) {

            ak[i][j] = pow(i, j);

        }

    }

}

ll f(int y,int k)

{

    ll sum = 0;

    while (y) {

        sum += ak[y % 10][k];

        y /= 10;

    }

    return sum;

}

void init_y()

{

    ll sum = 0;

    for (int k = 1; k <= 9; k ++) {

        for (int y = 0; y < 1e5; y ++) {

            sum = f(y, k);

            cnt[k][sum - y * 1e5] ++;

        }

    }

}


int main()

{

    init_ak();

    init_y();

    int T;

    cin >> T;

    for (int t = 1; t <= T; t ++) {

        int x,k;

        scanf("%d%d",&x,&k);

        ll ans = 0,key = 0;

        for (int i = 0; i < 1e5; i ++) {

            key = x - f(i,k) + i;//枚举y2

            if(cnt[k].find(key) != cnt[k].end()) {ans += cnt[k][key];}

        }

        if(x == 0) ans --;

        printf("Case #%d: %lld\n",t,ans);

    }

    return 0;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值