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

    【题目】

        一个给定的正整数序列,在每个数之前都插入+号或-号后计算它们的和。所有结果中至少有一个可被整数k整除,我们则称此正整数序列可被k整除。

        现判断一个正整数序列是否能被k整除。输入的第一行包含两个数:N(2 < N < 10000)和k(2 < k< 100),其中N代表一共有N个数,k代表被除数。

        第二行给出序列中的N个整数,这些整数的取值范围都0到10000之间(可能重复)。

    【题目链接】

        http://noi.openjudge.cn/ch0206/3531/

    【分析】

        1.  所谓递推就是一个问题与其子问题有一定的关系,为求解问题,应从子问题入手并记录子问题能提供的数据(及其状态),通过子问题的数据/状态逐步将子问题扩展为原问题。

        2.  该题的子问题就是该序列前i个数能否被k整除

        3.  再来看子问题状态,若仅仅提供该问题能否被k整除无法确定状态,根据mod运算的性质【(a+b)%k = (a%k+b%k)%k】不难想到,任意状态的值并不需要均求出来,而且任意两个状态如果相差k的整数倍则可将这两个状态视为等价,所以任意状态可映射到其对k取模之后的余数上去,当且仅当两个状态对k取模后余数相等可将这两个状态视为等价。由于一个子问题可能映射到多个余数,而k为2~100,所以定义子问题状态【bool 数组 b[i][j]的值表示序列前i个数所包含的状态除k余数是否可能为j】

        4.  再来看状态转移,若b[i-1][j]=1则b[i][(j+a[i]) % k] = 1, b[i][(j-a[i]+k) % k] = 1;初始情况则是b[1][a[1]] = 1;

    【代码】

     1 #include <iostream>
     2 using namespace std;
     3 int n,i,j,k;
     4 int a[10010];
     5 bool b[10010][110];
     6 int main()
     7 {
     8     cin>>n>>k;
     9     for(i = 1; i <= n; i++) cin>>a[i],a[i]%=k;
    10     b[1][a[1]] = 1;
    11     for(i = 2; i <= n; i++)
    12         for(j = 0; j < k; j++)
    13             if(b[i-1][j])
    14                 b[i][(a[i]+j)%k] = 1,
    15                 b[i][(j-a[i]+k)%k] = 1;
    16     if(b[n][0]) cout<<"YES";
    17     else cout<<"NO";
    18 }
  • 相关阅读:
    PHP编程资源
    JSP+Java编程资源
    Word、Excel办公书的资源下载
    听你说
    一些好看的渐变色(配色)网站推荐
    js判断数组中是否包含某个元素
    你才是你故事的作者
    vue-color 颜色选择器插件用法介绍
    vue-cli3 导入.md文件,vue中markdown文件的解析与渲染
    新版 animate.css 在vue中的正确使用
  • 原文地址:https://www.cnblogs.com/Willendless/p/9322414.html
Copyright © 2011-2022 走看看