思路:
数位dp,感觉可写的,结果一直WA,第一道Zoj的题,坑给了大数要%lld
读入….
- dp[i][j]:表示数位枚举到第i位,和为j的总花费(从高位枚举)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf=0xffffffff;
int t,x;
char s[20];
int a[20];
ll dp[20][100];
int v[16]={6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4};
ll dfs(int pos,int sum,bool limit){
if(pos<0)return sum;
if(!limit&&dp[pos][sum]!=-1)return dp[pos][sum];
ll ans=0;
int up=limit?a[pos]:15;
for(int i=0;i<=up;i++){
ans+=dfs(pos-1,sum+v[i],limit&&i==a[pos]);
}
if(!limit)dp[pos][sum]=ans;
return ans;
}
ll deal(){
ll tmp=0;
for(int i=0;i<8;i++){
tmp*=16;
if(s[i]<='9')tmp+=s[i]-'0';
else tmp+=s[i]-'A'+10;
}
return tmp;
}
ll solve(ll n){
int pos=0;
memset(a,0,sizeof(a));
while(n){
a[pos++]=n%16;
n/=16;
}
return dfs(7,0,1);
}
int main()
{
scanf("%d",&t);
memset(dp,-1,sizeof(dp));
while(t--){
scanf("%d %s",&x,s);
ll tmp=deal(),sum=tmp+x-1;
if(sum>inf)printf("%lld\n",solve(inf)+solve(sum-inf-1)-solve(tmp-1));
else printf("%lld\n",solve(sum)-solve(tmp-1));
}
return 0;
}