Description
17 + 5 + -21 - 15 = -14
17 + 5 - -21 + 15 = 58
17 + 5 - -21 - 15 = 28
17 - 5 + -21 + 15 = 6
17 - 5 + -21 - 15 = -24
17 - 5 - -21 + 15 = 48
17 - 5 - -21 - 15 = 18
We call the sequence of integers divisible by K if + or - operators can be placed between integers in the sequence in such way that resulting value is divisible by K. In the above example, the sequence is divisible by 7 (17+5+-21-15=-14) but is not divisible by 5.
You are to write a program that will determine divisibility of sequence of integers.
Input
The second line contains a sequence of N integers separated by spaces. Each integer is not greater than 10000 by it's absolute value.
Output
Sample Input
4 7 17 5 -21 15
Sample Output
Divisible
用到一個公式
(a + b) % c = (a % c + b % c) % c
當a小於0時 a對c的餘數 是 a % c + c
一個簡單的DP,不用把數字存起來,直接算就好。
AC代碼 :
使用了位運算來簡化空間複雜度,也可以使用滾動數組。(位運算的原理類似於滾動數組,把int的前兩位當作第一層數據和第二層然後每次結束右移單位1,覆蓋數據)
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define fn(i,n) for(int i = 0; i < n; i++)
int dp[110];
int main(){
int n, k, t;
while(scanf("%d %d",& n,& k) != EOF){
memset(dp,0,sizeof(dp));
cin >> t;
t = (t % k + k) %k; //無論t的正負取其餘數
dp[t] = 1;
fn(i,n - 1){
cin >> t;
t %= k;
if(t == 0) continue; //其實t = 0的話也可以接着算,不過爲了省時間還是判斷一下
fn(j,k) if(dp[j] & 1){ //判斷上一個數時是否有餘數
dp[(j + t + k) % k] |= 2; //第二位,置1
dp[(j - t + k) % k] |= 2;
}
fn(j,k) dp[j] >>= 1; //覆蓋上一組數據
}
if(dp[0])cout << "Divisible" << endl;
else cout << "Not divisible" << endl;
}
return 0;
}