POJ 2.6 3531 判断整除

3531:判断整除

总时间限制: 
1000ms 
内存限制: 
65536kB
描述

一个给定的正整数序列,在每个数之前都插入+号或-号后计算它们的和。比如序列: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
样例输出
NO

1.k是除数
2.(a%k+b%k)%k=(a+b)%k
3.((j-a[i]+k)%k)%k    //j-a[i]
=((j-a[i])%k+k%k)%k 
=((j-a[i])%k+0)%k
=(j-a[i])%k
可以看出,有没有+k)%k这部分,对结果没有影响,但会避免下标出现负数,使其变为正数
4.得到的和正负相对称

#include
using namespace std;
int main()
{
int a[10001]={0},n,k;
bool f[10001][101]={0};//每个i得到的余数可能有正负两个值,用bool型 ;f[i][j]表示用前i个数计算能得到余数j 
cin>>n>>k;
for (int i=1;i<=n;i++)
{
cin>>a[i]; a[i]%=k;
}
f[1][a[1]]=true;
for (int i=2;i<=n;i++)
for (int j=0;j<k;j++)
if (f[i-1][j]) {f[i][(j+a[i])%k]=true; f[i][((j-a[i]+k)%k)%k]=true;}//第一个%k避免下标出现负数 加法与%的交换律 
if (f[n][0]) cout<<"YES";else cout<<"NO";
return 0;
}

你可能感兴趣的:(POJ,text)