• hdu1573-X问题-(扩展欧几里得定理+中国剩余定理)


    X问题

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 8416    Accepted Submission(s): 3066


    Problem Description
    求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。
     
    Input
    输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。
     
    Output
    对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。
     
    Sample Input
    3 10 3 1 2 3 0 1 2 100 7 3 4 5 6 7 8 9 1 2 3 4 5 6 7 10000 10 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9
     
    Sample Output
    1 0 3
     
    #include <iostream>
    #include<stdio.h>
    #include <algorithm>
    #include<string.h>
    #include<cstring>
    #include<math.h>
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    
    int a[15];
    int r[15];
    int n,m,x,y;
    int lcm;
    int gcd;
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        int q=exgcd(b,a%b,y,x);
        y=y-(a/b)*x;
        return q;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            bool flag=true;
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++)
                scanf("%d",&a[i]);
            for(int i=0;i<m;i++)
                scanf("%d",&r[i]);
            int a1=a[0];
            int r1=r[0];
    
            for(int i=1;i<m;i++)
            {
                //printf("facai
    ");
                int b1=a[i];
                int r2=r[i];
                gcd=exgcd(a1,b1,x,y);
                int d=r2-r1;
                if(d%gcd)//无解
                    {flag=false;break;}
                int multiple=d/gcd;
                int p=b1/gcd;
                x=( (x*multiple)%p+p )%p;//最小正数解
                r1=x*a1+r1;//合并后更新余数
                a1=a1*b1/gcd;//更新除数为两者的最小公倍数
            }
            ///联立完所有的式子后,a1=lcm,r1也是终极余数
            ///求满足的k的数量 0<r1+lcm*k<=n
            ///k=(n-r1)/lcm ,  但是当r1=0时,k=0不能算进答案
            if(r1 > n) flag = false;
            int ans=0;
            if(flag)
            {
                ans=1+(n-r1)/a1;///k=0也算一个
                if(ans && r1==0) ans--;///ans至少要有一个才能自减,不然可能变成-1了
                printf("%d
    ",ans);
            }
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    iOS 9之后Url链接的NSUTF8StringEncoding转码实现
    iOS实现应用更新及强制更新
    Objective-C代码简写
    Mac下使用数据库将Excel数据转换存入.plist
    iOS开发之图片压缩实现
    iOS键盘事件实现、控制
    iOS 轻击、触摸和手势的检测
    使用CocoaPods时遇到 Permission denied 问题
    2016-3-1 Mac下使用Hexo搭建Blog
    2016-3-1 安装Hexo过程中遇到的问题
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10363497.html
Copyright © 2020-2023  润新知