版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/86553496
正题
题目大意
个盒子,
当第
个盒子中放了
,那么
个盒子中就必须放
(
)。
求
,
个盒子,求第一个盒子中可以放多少个
解题思路
1号盒子中的肯定越小越好。
要求满足条件那么首先
那么
。
然后奇数是肯定可以放进去的,
然后对于每个
,会封锁
。
之和我们会发现
又可以放进去了。
以此类推
我们可以发现
所以我们考虑枚举
。
开始先计算最大的
,统计一次奇数个数。
其实枚举
,就是每次让
除与
,然后统计一遍奇数个数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll mod=1e11;
const ll W=1000;
ll a[W+10],ans[W+10],m,t,l,al;
char s[W*10+10];
void print(ll x){
if (x>9) print(x/10); putchar(x%10+48); return;
}
void init()
{
memset(s,0,sizeof(s));
scanf("%s",s+1);
scanf("%lld",&m);
l=strlen(s+1);ll t=0,k=1;
for(ll i=l;i>=1;i--)
{
a[t]+=(s[i]-48)*k;k*=10;
if(k==mod) t++,k=1;
}
l=W;al=0;
}
void div(ll x)
{
ll g=0;
for(ll i=l;i>=0;i--)
{
a[i]+=g*mod;
g=a[i]%x;
a[i]/=x;
}
while(!a[l]&&l>=0)
l--;
}
void count_odd(){
ll g=0,i;
ans[0]+=a[0]%2;
for(i=l;i>=0;i--){
ans[i]+=(a[i]+g*mod)/2;
g=a[i]%2;
}
ll t=max(l-1,al);
if(ans[t+1]) t++;
for(i=0;i<=t;i++)
if(ans[i]>=mod)
{
ans[i+1]++;
ans[i]-=mod;
}
if(ans[i]>0) al=i;
else al=i-1;
}
void write()
{
print(ans[al]);
while(al--){
if(ans[al]<1e10) putchar(48);
if(ans[al]<1e9) putchar(48);
if(ans[al]<1e8) putchar(48);
if(ans[al]<1e7) putchar(48);
if(ans[al]<1e6) putchar(48);
if(ans[al]<1e5) putchar(48);
if(ans[al]<1e4) putchar(48);
if(ans[al]<1e3) putchar(48);
if(ans[al]<1e2) putchar(48);
print(ans[al]);
}
putchar('\n');
}
int main()
{
scanf("%lld",&t);
while(t--){
memset(a,0,sizeof(a));
memset(ans,0,sizeof(ans));
init();
div(1<<(m-1));
count_odd();
while(a[0]){
div(1<<m);
count_odd();
}
write();
}
}