撞杆子的CC学姐

描述

17级学姐中有个学姐,人称撞杆子的CC,因为CC学姐走路的时候总是在低头玩手机,所以经常撞杆子,在一次把鼻子撞破后,CC学姐在想自己出一次门究竟要撞多少个杆子。一天CC学姐打算去广场玩,已知CC学姐走完全程共撞n次杆子,CC学姐第一次撞杆子时是走了1米的时候,每次撞完杆子后潜意识都会改变自己的小心程度,即第i次撞杆子后经过2i % 107米后会撞下一个杆子,现在CC学姐想知道自己走了多远

格式

输入格式
输入一个n(1 <= n <= 10^5),CC学姐走完全程要撞的杆子数量
输出格式 
输出一个s,CC学姐走完全程所走的距离

样例

样例输入 Copy

1
3
4

样例输出 Copy

1
7
15

提示

多组测试数据,请在输入时循环输入到文件尾,共700组数据,请控制程序运行时间

分析题意:
撞n次杆子
第1次撞,走1米;( 2^0 m )
第i次撞杆子后(i+1次撞)经过2^i % 107 m后会撞下一个杆子
经过n次撞击,CC学姐走完全程所走的距离为
2^0
+2^1
+2^2
+……+2^n-1
根据这个公式,写出如下代码:

#include<stdio.h>
long long int fun(long long int a,long long int n)
{
      long long int ans=0,s=1;//ans 用来累计走完全程所走的距离
       while(n--)
     {
         ans+=s;
         s=s*2%107;
         //s从1开始,后面为2%107,4%107,8%107,16%107
     }
     return ans;
}
main()
{
    int n;
    while(~scanf("%d",&n))//输入要撞的杆子数n (1 <= n <= 10^5)
    printf("%lld\n",fun(2,n));
    //fun(2,n)是求CC学姐撞n个杆子走完全程所走的距离
}

当然,对于求2^i%107,可以想到用快速幂写。
先考虑a^b,再用取模公式
如求 5^10
1.指数10转二进制为1010
1 0 1 0
8 4 2 1
5^8 5^4 5^2 5^1
5^10 = 5^2 *5^8
二进制位为1,累乘,为0,不累乘
2. 从右至左依次取出1010的每一位
如b=10
b&1,(b>>1)&1,(b>>2)&1,(b>>3)&1………
直到b右移后为0停止

3.取模运算公式:
(ab) mod c = ((a mod c)(b mod c)) mod c
a^b mod c =((a mod c)^b) mod c

定义一个函数mode(int a,int b, int c),其作用为求a^b%c
b从0到n-1,在main函数中用for循环实现,并用ans累加
代码如下:

#include<stdio.h>
long long int mode(int a,int b,int c)//该函数作用求a^b%c
{
    long long int ans=1;//用于累乘
    a=a%c;
    while(b){
        if(b&1)//等同b%2==1
            ans=ans*a%c; 
        a=a*a%c;
        b>>=1;   //等同b/=2;
    }
    return ans;
}
main()
{
    int n;
    while(~scanf("%d",&n))
    {
        long long int ans=0;
        for(int i=0;i <= n-1;i++){
            ans+=mode(2,i,107);
        }
        printf("%lld\n",ans);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值