DUTOJ1205(大数)

1205: 对圣杯宝具的威力值

Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:179   Accepted:34

[Submit][Status][Discuss]

Description

当我掏出咖喱棒,没有圣杯能够立在我的面前。

对圣杯宝具咖喱棒是saber拥有的一种大规模杀伤性武器,士郎很好奇saber手中的咖喱棒到底有多大威力,于是他开始观察咖喱棒释放时出现的光粒。他认为,咖喱棒的威力值与光粒的数量存在某种关系。

光粒的数目是一个很大的整数xx,士郎发现,咖喱棒的威力值恰好是lowbit(x)。即把x转化为2进制后,只保留最低位的1及其后面的0,去掉前面的内容,所代表的10进制数,如6(110)的lowbit为2(10),12(1100)的lowbit为4(100),20(10100)的lowbit也为4(100)。

切嗣并没有教士郎怎么使用电脑,所以士郎想请你帮忙算出咖喱棒的威力值,这个威力值可能很大所以你只需要输出它除109+7109+7的余数即可。

本题数据组数:不计样例仅1组

Input

第一行输入一个整数t,表示测试数据组数。

接下来t行,输入一行,一个长度不超过103103的字符串,代表光粒数xx。

Output

 输出t行,每行一个整数,表示取模后的威力值对取余后的109+7109+7值

Sample Input

140

Sample Output

8

HINT

吾王剑锋所指,吾等心之所向

 

汤大佬出的大数,没有卡常数,只要判断末尾是不是奇数然后一直除以二就好。提供两种写法一种是正常写法(16ms)另一个是int存4位数字(5ms),大幅度底稿运算速度,poj上有一题求阶乘只有用这种骚操作才过得了。将来不那么菜了学学python和java应该会好写很多。

#include<bits/stdc++.h>
using namespace std;
int len;
char ss[3100];int st;int s[3100];
void chu()
{
int flag=1;
for(int i=st;i<len;i++)
{
if(s[i]&1)
{
s[i+1]+=10;
}
s[i]=s[i]>>1;
if(flag)
{
if(s[i]==0)
{
st++;
}
else flag=0;
}
}
}
int main(){
int t;int ans;
scanf("%d",&t);
while(t--)
{
scanf("%s",ss); 
len=strlen(ss);
for(int i=0;i<len;i++)
{
s[i]=ss[i]-'0';
}
ans=1;st=0; //printf("%d~~\n",s[len-1]&1);
while(!(s[len-1]&1))
{
chu();  
//printf("!!\n");
ans=ans<<1;ans%=1000000007;
}
printf("%d\n",ans);
}

}



 

方法2

        
 

         
        #include<bits/stdc++.h>


using namespace std;
int num[3010];
char s[3010];
int nlen;


void chu()
{
for(int i=nlen;i>0;i--)
{
if(num[i]&1)
{
num[i-1]+=10000;
}
num[i]=num[i]>>1;
}
// printf("~~num0 %d\n",num[0]);
if(num[nlen]==0)
{
nlen--;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
int i;int ans=1;
int slen=strlen(s);int te;
for(i=1;4*i<slen;i++)
{
sscanf(s+slen-4*i,"%4d",&num[i]);
}sscanf(s,"%d",&te);
if(slen!=4*i-4)
{
slen-=4*i-4;s[slen]='\0';sscanf(s,"%d",&num[i]);
}
nlen=i;
/* for(i=0;i<10;i++)
{
printf(" %d ",num[i]);
}printf("%d~~~!~!~!~!\n",nlen);*/ 
while(!(num[1]&1))
{
ans=ans<<1;
// printf("ans%d\n",ans);
ans%=1000000007;
chu();
/* for(i=0;i<10;i++)
{
printf(" %d ",num[i]);
}printf("%d~~~!~!~!~!\n",nlen);*/
}
printf("%d\n",ans); 
// printf("%d\n",te&(-te));
}

} 
    


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值