HDU - 5936: Difference(中途相遇法)

Posted hua-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 5936: Difference(中途相遇法)相关的知识,希望对你有一定的参考价值。

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

f(y,K)=z in every digits of yzK(f(233,2)=22+32+32=22)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)yx=f(y,K)−y


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

InputFirst line contains an integer TT, which indicates the number of test cases. 

Every test case contains one line with two integers xx, KK. 

Limits 
1T1001≤T≤100 
0x1090≤x≤109 
1K91≤K≤9
OutputFor 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

题意:给定函数f(y,K)=∑y的所有位的K次幂,给出X,K,问多少个Y满足f(Y,K)=X;

思路:似乎没有什么思路,考虑暴力,估计Y只有10位,所以我们暴力前面5位,用map去寻找后面5位。

然而我开始些了离散化WA了,map过了。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
unordered_map<ll,int>mp;
ll tot,cnt,f[10][10],K,a[maxn],X,ans,num[maxn];
int main()
{
    int T,Cas=0;
    scanf("%lld",&T); rep(i,0,9) f[i][0]=1;
    rep(i,1,9) rep(j,1,9) f[i][j]=f[i][j-1]*i;
    while(T--){
        tot=cnt=0; mp.clear();
        scanf("%lld%lld",&X,&K); ans=0;
        rep(i,0,9)
         rep(j,0,9)
          rep(k,0,9)
           rep(p,0,9)
            rep(q,0,9){
             ll t1=f[i][K]+f[j][K]+f[k][K]+f[p][K]+f[q][K],t2=i*10000+j*1000+k*100+p*10+q;
             a[++tot]=t1-100000LL*t2; mp[t1-t2]++;
             if(t1-t2==X) ans++;
        }
        rep(i,2,tot) if(mp.find(X-a[i])!=mp.end())ans+=mp[X-a[i]];
        printf("Case #%d: %lld
",++Cas,ans-(X==0));
    }
    return 0;
}

错误代码(依然没有找到bug):

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
int Laxt[maxn],Next[maxn],tot,cnt,f[20][20],num[maxn]; ll a[maxn],To[maxn],X,ans,K;
int find(ll x){
    ll t=(x%maxn+maxn)%maxn;
    for(int i=Laxt[t];i;i=Next[i]) if(To[i]==x) return num[i];
    return 0;
}
void add(ll x){
    if(x==X) ans++;
    ll t=(x%maxn+maxn)%maxn;
    for(int i=Laxt[t];i;i=Next[i]){
        if(To[i]==x) { num[i]++; return ;}
    }
    Next[++cnt]=Laxt[t]; Laxt[t]=++cnt; To[cnt]=x; num[cnt]=1;
}
int main()
{
    int T,Cas=0;
    scanf("%lld",&T); rep(i,0,9) f[i][0]=1;
    rep(i,1,9) rep(j,1,9) f[i][j]=f[i][j-1]*i;
    while(T--){
        memset(Laxt,0,sizeof(Laxt));
        tot=cnt=0;
        scanf("%lld%lld",&X,&K); ans=0;
        rep(i,0,9)
         rep(j,0,9)
          rep(k,0,9)
           rep(p,0,9)
            rep(q,0,9){
             ll t1=f[i][K]+f[j][K]+f[k][K]+f[p][K]+f[q][K],t2=i*10000+j*1000+k*100+p*10+q;
             a[++tot]=t1-100000LL*t2; add(t1-t2);
        }
        rep(i,2,tot) ans+=find(X-a[i]);
        printf("Case #%d: %lld
",++Cas,ans-(X==0));
    }
    return 0;
}

 

以上是关于HDU - 5936: Difference(中途相遇法)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5936 Difference 中途相遇法(中国大学生程序设计竞赛(杭州))

HDU-5936 Difference(折半枚举)

HDU 5936 Difference(思维+二分)——2016年中国大学生程序设计竞赛(杭州)

HDU 5936 朋友

HDU-4715 Difference Between Primes(线性筛法)

HDU 5486 Difference of Clustering 图论