zoukankan      html  css  js  c++  java
  • 判断整除

    判断整除

    链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1195


    时间限制: 1000 ms         内存限制: 65536 KB

    【题目描述】

    一个给定的正整数序列,在每个数之前都插入+号或-号后计算它们的和。比如序列:1、2、4共有8种可能的序列:

    (+1) + (+2) + (+4) = 7

    (+1) + (+2) + (-4) = -1

    (+1) + (-2) + (+4) = 3

    (+1) + (-2) + (-4) = -5

    (-1) + (+2) + (+4) = 5

    (-1) + (+2) + (-4) = -3

    (-1) + (-2) + (+4) = 1

    (-1) + (-2) + (-4) = -7

    所有结果中至少有一个可被整数k整除,我们则称此正整数序列可被k整除。例如上述序列可以被3、5、7整除,而不能被2、4、6、8……整除。注意:0、-3、-6、-9……都可以认为是3的倍数。

    【输入】

    输入的第一行包含两个数:N(2<N<10000)和k(2<k<100),其中N代表一共有N个数,k代表被除数。第二行给出序列中的N个整数,这些整数的取值范围都0到10000之间(可能重复)。

    【输出】

    如果此正整数序列可被k整除,则输出YES,否则输出NO。(注意:都是大写字母)

    【输入样例】

    3 2
    1 2 4
    法一:搜索,对于每个数非正即负,用X代表抉择,F[i]表示选到第i个数得到答案
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cmath>
    using namespace std;
    int f[10005],a[10005];
    int n,k,cnt;
    void dfs(int i,int x){
        
        if(i==n+1)
        {
            if(cnt){
                return ;
            }
            f[i-1]=abs(f[i-1]);
            if(f[i-1]%k==0)
                cnt=1;
            return ;                
        }
        if(cnt){
            return ;
        }
        if(x)f[i]=f[i-1]+a[i];
        else f[i]=f[i-1]-a[i];
        dfs(i+1,0);    
        dfs(i+1,1);
    
    }
    int main()
    {
        int ans=0;
        cin>>n>>k;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            ans+=a[i];
        }
        f[0]=0;
        if(ans%2&&k%2==0);    
        else {
            dfs(1,0);
            if(cnt){
                cout<<"YES"<<endl;
                return 0;
            }
            else {
                dfs(1,1);
                if(cnt){
                    cout<<"YES"<<endl;
                    return 0;
                }
            }
        }
        
        if(!cnt)cout<<"NO"<<endl;
        return 0;
    }
    
    

    法二:递推,f[i][j]表示用了第i个数能否使余数为j,若f[n][0]为真则成立,得到转移方程:

     f[i][j]=(f[i-1][((j-a[i])%k+k)%k]||f[i-1][(j+a[i])%k]);//加上k是为了使下标大于1   →(a*b)%c=(a%c+b%c)%c;

    对于边界1可只考虑+或-,因为一种情况整体乘-1就得到另一种情况,见样例

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    bool f[10005][205];
    int a[10005];
    int main()
    {
        int n,k;
        cin>>n>>k;
        for(int i=1;i<=n;i++)cin>>a[i];
        f[1][(a[1]%k+k)%k]=1;
        for(int i=2;i<=n;i++)
            for(int j=0;j<k;j++){
                f[i][j]=(f[i-1][((j-a[i])%k+k)%k]||f[i-1][(j+a[i])%k]);
        }
        if(f[n][0])cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }


  • 相关阅读:
    C++中整型变量的存储大小和范围
    A1038 Recover the Smallest Number (30 分)
    A1067 Sort with Swap(0, i) (25 分)
    A1037 Magic Coupon (25 分)
    A1033 To Fill or Not to Fill (25 分)
    A1070 Mooncake (25 分)
    js 获取控件
    C#代码对SQL数据库添加表或者视图
    JS 动态操作表格
    jQuery取得下拉框选择的文本与值
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/7530590.html
Copyright © 2011-2022 走看看