poj 1745 Divisibility (利用余数个数有限巧解)

题目链接: 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值