参考别人的代码,自己也敲了一遍,
思路大概该是 从小 到 大 的 一次 算 每位数 出现的次数
参考自 http://blog.csdn.net/crazy_calf/article/details/70578679
/*#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<set>
#include<vector>
#include<algorithm>
typedef long long ll;
using namespace std;
int f[20]={6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4};
ll num[20];
int main(){
int t,n;
char s[20];
scanf("%d",&t);
while(t--){
scanf("%d%s",&n,s);
memset(num,0,sizeof(num));
ll c=16,d=1;
ll k=0;
for(int i=7;i>=0;i--){
ll nn=n;
ll kk1,kk2;
if(s[i]>='A'&&s[i]<='Z')kk1=s[i]-'A'+10;
else kk1=s[i]-'0';//kk1表示这一位数
kk2=kk1;
if(k>=n)//还要多少秒来影响它
{num[kk1]+=n;continue;}
nn-=k; //后面全0
num[kk1]+=k;//这一位数已经保持了k秒
ll t1=nn/c; //出现好多次 16->16^t
ll t2=nn%c; //剩下好多秒
for(int j=0;j<16;j++){
num[j]+=d*t1;// 每一位都增加 d*t1 这么多次 d多少秒吧
}
if(i!=7)kk1++; //不等于最低位,kk1++,kk1这一位已经算完
for(ll j=t2;j>0;j-=d){//剩下的数
num[kk1%16]+=min(j,d);//除了最后一次可能取j 其余都是d
kk1++;//循环取数字
}
if(i==7)k+=16-kk2; // 最低位好多影响前一位
else k+=(15-kk2)*d;// 不是最低位 则好多影响最高位
d*=16;
c*=16;
}
ll ans=0;
for(int i=0;i<16;i++){
ans+=f[i]*num[i];
}
printf("%lld\n",ans);
}
return 0;
}
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
ll n;
ll f[20];
char s[10];
ll cost[16]={6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4};
int main()
{
int t;
cin>>t;
ll k,k1,k2,t1,t2,nn;
ll d,c;
while(t--)
{
memset(f,0,sizeof(f));
scanf("%lld%s",&n,&s);
d=1;
c=16;
k=0;
for(int i=7;i>=0;i--)
{
nn=n;
if(s[i]>='A'&&s[i]<='F')
k1=s[i]-'A'+10;
else
k1=s[i]-'0';
k2=k1;
if(k>=n)
{
f[k1]+=n;
continue;
}
nn-=k;
f[k1]+=k;
t1=nn/c;
t2=nn%c;
for(int j=0;j<16;j++)
{
f[j]+=d*t1;
}
if(i!=7)
k2++;
for(ll j=t2;j>0;j-=d)
{
f[k2%16]+=min(j,d);
k2++;
}
if(i==7)
{
k+=16-k1;
}
else
{
k+=(15-k1)*d;
}
c*=16;
d*=16;
}
ll ans=0;
for(int i=0;i<16;i++)
{
ans+=f[i]*cost[i];
}
printf("%lld\n",ans);
}
return 0;
}