zoukankan      html  css  js  c++  java
  • HDU 5690——All X——————【快速幂 | 循环节】

    All X

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 879    Accepted Submission(s): 421


    Problem Description
    F(x,m) 代表一个全是由数字x组成的m位数字。请计算,以下式子是否成立:

    F(x,m) mod k  c
     
    Input
    第一行一个整数T,表示T组数据。
    每组测试数据占一行,包含四个数字x,m,k,c

    1x9 

    1m1010

    0c<k10,000
     
    Output
    对于每组数据,输出两行:
    第一行输出:"Case #i:"。i代表第i组测试数据。
    第二行输出“Yes” 或者 “No”,代表四个数字,是否能够满足题目中给的公式。
     
    Sample Input
    3
    1 3 5 2 1 3 5 1 3 5 99 69
     
    Sample Output
    Case #1: No Case #2: Yes Case #3: Yes
    Hint
    对于第一组测试数据:111 mod 5 = 1,公式不成立,所以答案是”No”,而第二组测试数据中满足如上公式,所以答案是 “Yes”。
     
    Source
     
     
    解题思路:打表找循环节。
     
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<string>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<map>
    #include<vector>
    #include<set>
    using namespace std;
    typedef long long LL;
    #define mid (L+R)/2
    #define lson rt*2,L,mid
    #define rson rt*2+1,mid+1,R
    #pragma comment(linker, "/STACK:102400000,102400000")
    const int maxn = 1e5 + 300;
    const LL INF = 0x3f3f3f3f;
    typedef long long  LL;
    typedef unsigned long long ULL;
    LL vis[maxn], a[maxn];
    int main(){
        LL x, m, k, c;
        int T, cas = 0;
        scanf("%d",&T);
        while(T--){
            scanf("%lld%lld%lld%lld",&x,&m,&k,&c);
            memset(vis,0,sizeof(vis));
            int nn = 0, le = 0, st = 1;
            LL cc;
            LL n = 0;
            for(int i = 1; ; i++){
                n = n*10;
                n = n + x;
                n = n%k;
                if(vis[n]){
                    cc = n;
                    break;
                }else{
                    vis[n] = 1;
                    nn++;
                    a[nn] = n;
                }
            }
            for(int i = 1; i <= nn; i++){
                if(a[i] == cc){
                    le = nn+1 - i;
                    st = i;
                    break;
                }
            }
            int flag = 0;
            if(m < st){
                if(a[m] == c){
                    flag = 1;
                }
            }else{
                m -= st;
                m %= le;
                if(a[st+m] == c){
                    flag = 1;
                }
            }
            printf("Case #%d:
    ",++cas);
            if(flag) puts("Yes");
            else puts("No");
        }
        return 0;
    }
    
    
    
    /*
    55
    3 5 99 69
    
    3 4 4 2
    3 8 4 2
    
    2 8 3 2
    
    */
    

      

    解题思路:数学方法。

    转自http://m.blog.csdn.net/article/details?id=51471639

    这个数要mod k ,那这个数应该怎么表示呢?

    就这样转化了,然后10^m可以通过快速幂解决,但是很明显,除以9操作怎么办,除法取模,余数是会改变的,逆元?但是9和k不一定互质,且k也不一定是质数,所以扩展欧几里得和费马小定理都不能用了,束手无策

    好吧,这里提供一种小方法

    就这样经过几步转化,我求d不需要进行除法取模了,那我上面的问题不就解决了?对的。

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<string>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<map>
    #include<vector>
    #include<set>
    using namespace std;
    typedef long long LL;
    #define mid (L+R)/2
    #define lson rt*2,L,mid
    #define rson rt*2+1,mid+1,R
    #pragma comment(linker, "/STACK:102400000,102400000")
    const int maxn = 1e5 + 300;
    const LL INF = 0x3f3f3f3f;
    typedef long long  LL;
    typedef unsigned long long ULL;
    LL quick(LL x,LL n,LL p){
        if(n == 0) return 1;
        LL ret = 1;
        while(n){
            if(n&1) ret = ret*x % p;
            n = n >> 1;
            x = x*x % p;
        }
        return ret;
    }
    int main(){
        LL x, m, k, c;
        int T, cas = 0;
        scanf("%d",&T);
        while(T--){
            scanf("%lld%lld%lld%lld",&x,&m,&k,&c);
            k*=9;
            LL ans = quick(10,m,k);
            ans = (ans - 1 + k) % k;
            ans /= 9;
            k /= 9;
            ans = ans * x % k;
            bool flag = 0;
            if(ans == c)
                flag = 1;
            printf("Case #%d:
    ",++cas);
            if(flag) puts("Yes");
            else puts("No");
        }
        return 0;
    }
    
     
    

      

  • 相关阅读:
    网络编程
    C 语言 const
    C 语言 链表
    C 语言 按位计算
    C 语言 格式化输出输入
    C 语言 结构类型 联合
    C 语言 结构类型 结构
    C 语言 结构类型 枚举
    bash shell configuration
    sed usage
  • 原文地址:https://www.cnblogs.com/chengsheng/p/5521041.html
Copyright © 2011-2022 走看看