zoukankan      html  css  js  c++  java
  • UVALive 4998 Simple Encryption --DFS

    题意: 给出K1,求一个12位数(不含前导0)K2,使得K1^K2 mod (10^12) = K2.

    解法: 求不动点问题。

    有一个性质: 如果12位数K2满足如上式子的话,那么K2%1,K2%10,K2%100,...,K2%10^12都会满足如上式子。那么我们可以dfs从后往前一个一个找出这个数的每一位。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define SMod 1000000000000
    #define ll long long
    using namespace std;
    #define N 10007
    
    ll K1,K2;
    long long mul(long long a,long long b,long long mod) {
        ll ite = (1LL<<20)-1;
        return (a*(b>>20)%mod*(1ll<<20)%mod+a*(b&(ite))%mod)%mod;
    }
    
    ll fastm(ll a,ll b,ll m) {
        ll res = 1LL;
        while(b) {
            if(b&1LL) res = mul(res,a,m);
            a = mul(a,a,m);
            b >>= 1;
        }
        return res;
    }
    
    ll wei[16],ans;
    
    bool dfs(int c,ll now) {
        if(c == 13) {
            if(now >= wei[12]) { ans = now; return true; }
            return false;
        }
        ll W = wei[c];
        for(ll i=0;i<=9;i++) {
            ll tmp = W*i+now;
            if(fastm(K1,tmp,W) != tmp%W) continue;
            if(dfs(c+1,tmp)) return true;
        }
        return false;
    }
    
    int main()
    {
        int t,cs = 1;
        wei[0] = 1LL;
        for(int i=1;i<=13;i++) wei[i] = wei[i-1]*10LL;
        while(scanf("%lld",&K1)!=EOF && K1) {
            dfs(0,0);
            printf("Case %d: Public Key = %lld Private Key = %lld
    ",cs++,K1,ans%SMod);
        }
        return 0;
    }
    View Code

    还有一种循环迭代的方法,随机选取一个超过10^12的数,如1000000000007,将其代入计算,如果f(x)!=x,那么令x=f(x),如此循环,能在短时间内找出合法解。不知道为啥。。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define SMod 1000000000000
    #define ll long long
    using namespace std;
    
    ll K1,K2;
    long long mul(long long a,long long b,long long mod) {
        ll ite = (1LL<<20)-1;
        return (a*(b>>20)%mod*(1ll<<20)%mod+a*(b&(ite))%mod)%mod;
    }
    
    ll fastm(ll a,ll b,ll m) {
        ll res = 1LL;
        while(b) {
            if(b&1LL) res = mul(res,a,m);
            a = mul(a,a,m);
            b >>= 1;
        }
        return res;
    }
    ll f(ll x) {
        return fastm(K1,x,SMod);
    }
    ll gao(ll x) {
        while(1) {
            ll fx = f(x);
            if(fx == x) return x;
            x = fx;
        }
    }
    
    int main()
    {
        int t,cs = 1;
        while(scanf("%lld",&K1)!=EOF && K1) {
            printf("Case %d: Public Key = %lld Private Key = %lld
    ",cs++,K1,gao(1000000000007));
        }
    }
    View Code
  • 相关阅读:
    定位
    supervisor进程管理工具
    简单git使用命令
    django + Vue项目上线部署
    Vue配置浏览器头部图标和title
    vue打包项目后 谷歌浏览器可以打开,其他浏览器不行
    js反向解析爬取企**网站
    python常用排序算法
    python脚本demo
    request模块封装
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4234632.html
Copyright © 2011-2022 走看看