HDU Difference (折半二分思想 + 数据结构的使用)

本文介绍了一种基于数位的动态规划问题解决方法,并通过一个具体的编程挑战实例进行了详细解析。该方法通过预处理和分段枚举的方式,有效地减少了搜索空间,实现了对特定类型数学问题的有效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Difference

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1432    Accepted Submission(s): 392


Problem Description
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
 

Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result.
 

Sample Input

 
2 2 2 3 2
 

Sample Output

 
Case #1: 1 Case #2: 2
 

Source
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:   6297  6296  6295  6294  6293 
#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define mod 1e9+7
#define ll long long
#define maxn 100001
#define UB 100000
using namespace std;

const int t[]={1,10,100,1000,10000,100000};
int x,k;
int Pow[13][13];///i的j次方
map<ll,int> cnt[10];///贡献度为i的方案,
///如果一些指标或者索引以负数的形式出现那么map是个很好的手段

/*
题目大意:给定一个公式,
里面的变量有三个,x,y,k;
现已知x和k,那么满足条件的y有多少个。

首先一个关键的枚举突破点是y的范围,
不超过10^10范围,所以对于指标里面参杂者数位的因素时
(比如这道题是每位数的平方和),
所以可以对半枚举,五位数五位数的枚举。
预先处理五位数的情况形成的,然后对于枚举的给定的y,通过
从表中查找并更新答案即可。。

细节:当x为0时,y不为0,因为y的范围不允许,所以最后答案减一。


*/
void pre_work()
{
    for(int i=0;i<10;i++)
    {
        Pow[i][0]=1;
        for(int j=1;j<=10;j++)
            Pow[i][j]=Pow[i][j-1]*i;
    }

    for(int k=1;k<=9;k++)
    {
        for(int i=0;i<1e5;i++)
        {
            ll res=-i;
            for(int j=0;j<5;j++)
                 res+=Pow[i/t[j]%10][k];
            cnt[k][res]++;
        }
    }
}

int main()
{
    pre_work();
    int T;cin>>T;
    for(int cas=1 ; cas<=T ; cas++)
    {
        scanf("%d%d",&x,&k);
        ll ans=0;
        for(int i=0;i<1e5;i++)
        {
            ll res=-i*(1e5);
            for(int j=0;j<5;j++)
                res+=Pow[i/t[j]%10][k];
            ll tar=x-res;
            if(cnt[k].find(tar)!=cnt[k].end())
                ans += cnt[k][tar] ;
        }
        if(x==0) ans--;
        printf("Case #%d: %lld\n",cas,ans);
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值