zoj3962

作者: _弓长_大人 | 来源:发表于2018-09-25 12:47 被阅读4次

参考别人的代码,自己也敲了一遍,
思路大概该是 从小 到 大 的 一次 算 每位数 出现的次数
参考自 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;
}

相关文章

  • zoj3962

    参考别人的代码,自己也敲了一遍,思路大概该是 从小 到 大 的 一次 算 每位数 出现的次数参考自 http://...

网友评论

      本文标题:zoj3962

      本文链接:https://www.haomeiwen.com/subject/dofozttx.html