把这两天写的的好题放一放,需要在消化消化。
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3962
思路:
1.设num1为起点,num2为终点,计算00000000到终点的耗费能量,在计算00000000到起点-1的耗费能量,相减即为所求答案。
过了FFFFFFFFF又会到起点,所以分两种情况讨论。
2.分别计算每位的耗费能量,累和即为答案。简单模拟下装置运行,发现求出循环次数,循环1次的时间,循环完在计算0~这位上的数字-1的能量和时间,在计算这位上数字的能量和时间,即可把所有情况囊括其中。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int gx[16]={6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4},sum[20];
const ll MOD=(1LL<<32); //注意加LL,否则爆
ll n,m,ans,res;
void pre()
{
sum[0]=0;
for(int i=1;i<=16;i++) sum[i]=sum[i-1]+gx[i-1];
return ;
}
void read()
{
scanf("%lld %llx",&n,&m);
return ;
}
ll calc(ll x)
{
if(x<0) return 0; //situation of 0x00000000 subtract 1
ll a,b,c;
ll mul=1,ans=0;
for(int i=1;i<=8;i++)
{
a=x/(16*mul)*sum[16];
b=sum[x/mul%16];
c=(x%mul+1)*gx[x/mul%16];
ans+=(a+b)*mul+c;
mul*=16;
// printf("%lld %lld %lld %lld\n",a,b,c,ans);
}
return ans;
}
void judge()
{
if(n+m-1>=MOD) res=calc(MOD-1)-calc(m-1)+calc(n+m-1-MOD);
else res=calc(n+m-1)-calc(m-1);
return ;
}
void print()
{
printf("%lld\n",res);
}
int main()
{
pre();
int t;
cin>>t;
while(t--)
{
read();
judge();
print();
}
return 0;
}