• CF 345A Mike and Frog


    题目

    自己歪歪的做法WA了好多发。
    原题中每一秒都相当于
    $x1 = f1(x1)$
    $x2 = f2(x2)$
    然后这是一个定义域和值域都在[0,m-1]的函数,显而易见其会形成一个环。
    而且环长不超过m,所以实际上问题就分为了两部分:
    1.x1变到a1,x2变到a2(h -> a的长度)
    2.x1做循环,x2做循环直到同时为a1,a2。(a -> a的长度)
    我们设第一步分别用了m1 s, m2 s,第二步用了 t1 s ,t2 s。
    对于第一部分我们可以直接枚举吗,因为长度不超过m。
    对于第二部分实际上是两个式子。
    $ans =  △1 * t1 + m1$
    $ans =  △2 * t2 + m2$
    这个式子只需要枚举就行了。因为m1,m2最多相差不超过m,而在最优决策下△1或△2绝对值每变化1,m1,m2必然至少变化1,所以△最大为m
    问题解决,注意各种特判,比如都没有t值,有一个有t值,无解的情况。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    
    #define LL long long
    
    using namespace std;
    
    LL m,ans;
    
    LL gcd(LL a,LL b){
        if(!b) return a;
        return gcd(b,a%b);
    }
    
    /*
    since the f(x) be an fuction from a num x to y.
    so it may be a cricle.
    */
    
    void solve(LL &ansv,LL &sumv){
        LL h,a,x,y,ans=0;
        scanf("%I64d%I64d%I64d%I64d",&h,&a,&x,&y);
        for(int i=1;i<=m;i++){
            h=(h*x%m+y)%m;
            if(h==a){
                ansv=(LL)i;    //how many seconds it would take for us to arrive 'a' from 'h'
                goto L;
            }
        }
        puts("-1");
        exit(0);
        L:h=a;
        sumv=-1;
        for(int i=1;i<=m;i++){
            h=(h*x%m+y)%m;    //how many seconds it would take for us to arrive 'a' from 'a'
            if(h==a){
                sumv=(LL)i;
                return;
            }
        }
    }
    
    /*
    a1 + k1*a2 = b1 + k2*b2
    
    ans = a1 (mod a2)
    ans = b1 (mod b2)
    */
    
    int main(){
        scanf("%I64d",&m);
        LL a1,a2,b1,b2;
        solve(a1,a2);
        solve(b1,b2);
        if(a1==b1) ans=a1;
        else if(a2==-1&&b2==-1){
            puts("-1");
            return 0;
        }
        else if(a2==-1&&a1>b1&&(a1-b1)%b2==0) ans=a1;
        else if(b2==-1&&b1>a1&&(b1-a1)%a2==0) ans=b1;
        else if(a2==-1||b2==-1){
            puts("-1");
            return 0;
        }
        else{
            LL k1;
            for(k1=0;k1<=m;k1++)
                if((a1+k1*a2-b1)%b2==0){
                    ans=a1+k1*a2;
                    if(ans>=b1) break;
                }
            if(k1>m) ans=-1;
        }
        printf("%I64d
    ",ans);
        return 0;
    }
    Code
  • 相关阅读:
    NodeJs操作MongoDB之分页功能与常见问题
    NodeJs之word文件生成与解析
    NodeJs之EXCEL文件导入导出MongoDB数据库数据
    NodeJs之文件上传
    NodeJs之定时器与队列
    NodeJs操作MongoDB之多表查询($lookup)与常见问题
    Windows下安装配置MongoDB
    关于fastJson的几个问题
    (转)java并发编程:CopyOnWriteArrayList
    java并发编程:锁的相关概念介绍
  • 原文地址:https://www.cnblogs.com/lawyer/p/4548212.html
Copyright © 2020-2023  润新知