题目链接: http://poj.org/problem?id=1745
题意: 给n个数,数间可以填加或减,问是否有一种结果是k的倍数;
分析: n<=10000, k<=100. 这题一看到什么整除的,我马上想到了利用余数个数解,之前我在zoj,hdoj,遇到过类似的题目; zoj上有道分支限界搜索的就是利用余数来优化的。hdoj那道是利用0到9这些数组成一个数的倍数,要求是不同的数字最少而且相同数字个数的情况下去更小的,有个结论只需两个数字就可以组成一个数的倍数。 那道题挺好的。 以前写的,如有描述错误,请多指正。 本想把那两题的链接找来的,找了很就都没找到就放弃了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace:: std;
#define maxn 108
int n, K;
int a[maxn*maxn];
bool dp[2][maxn<<1];
int main(){
while( ~scanf ("%d%d", &n, &K) ) {
for ( int i(0); i<n; ++i )
scanf ("%d", a+i);
memset(dp, 0, sizeof dp);
int cnt = 1;
dp[1][ a[0]%K+ 100 ] = true;
for ( int i=1; i<n; ++i ) {
cnt ^= 1;
memset(dp[cnt], 0, sizeof dp[cnt]);
for ( int j=0; j<K+100; ++j ) if(dp[cnt^1][j] )
{
dp[cnt][(j-100+a[i])%K+100] = true;
dp[cnt][(j-100-a[i])%K+100] = true;
}
}
puts(dp[n&1][100]? "Divisible": "Not divisible");
}
};
其实这个只要知道是利用余数来解,写法也是很暴力的。 貌似我这种做法不是很好,跑的300+ms,那些大神都是几十ms秒掉此题的。额 ,突然想到set可以优化的,o(╯□╰)o