P1356 數列的整除性

dp百題進度條[2/100]算法

題目連接dom

題目描述
對於任意一個整數數列,咱們能夠在每兩個整數中間任意放一個符號'+'或'-',這樣就能夠構成一個表達式,也就能夠計算出表達式的值。好比,如今有一個整數數列:17,5,-21,-15,那麼就能夠構造出8個表達式:spa

17+5+(-21)+15=16
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

對於一個整數數列來講,咱們能經過如上的方法構造出不一樣的表達式,從而獲得不一樣的數值,若是該數值可以被k整除的話,那麼咱們就稱該數列能被k整除。 在上面的例子中,該數列能被7整除(17+5+(-21)-15=--14),但不能被5整除。如今你的任務是,判斷某個數列是否能被某數整除。code

輸入格式
第一行是一個整數m,表示有m個子任務。接下來就是m個子任務的描述。 每一個子任務有兩行。第一行是兩個整數n和k(1<=n<=10000, 2<=k<=100),n和k中間有一個空格。n 表示數列中整數的個數;k就是須要你判斷的這個數列是否能被k 整除。第二行是數列的n個整數,整數間用空格隔開,每一個數的絕對值都不超過10000。get

輸出格式
輸出文件應有m 行,依次對應輸入文件中的m 個子任務,若數列能被k 整除則輸出 "Divisible",不然輸出 "Not divisible" ,行首行末應沒有空格。string

輸入輸出樣例
輸入 #1
2
4 7
17 5 -21 15
4 5
17 5 -21 15
輸出 #1
Divisible
Not divisibleio

思路一:正常的dp
0/1揹包,本身看就好惹方法

Code

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 10005;

int x,k,n;
bool dp[MAXN][1005];
inline int mod(int x){
    x %= k;
    if (x < 0) x += k;
    return x;
}
int main(){
    int t;
    scanf("%d",&t);
    
    while (t--){
        scanf("%d %d",&n,&k);
        
        memset(dp,false,sizeof(dp));
        
        scanf("%d",&x);
        
        dp[0][mod(x)] = true;
        dp[0][mod(-x)] = true;
        
        for (register int i = 1 ; i < n ; i++){
            scanf("%d",&x);
            x = mod(x);
            for (register int j = 0 ; j < k ; j++){
                dp[i][j] = dp[i - 1][mod(j - x)] | dp[i - 1][mod(j + x)];
            } 
        }
        
        if (t == 0){
            if (dp[n - 1][0] == true) printf("Divisible");
            else printf("Not divisible");
        }
        
        else{
            if (dp[n - 1][0] == true) printf("Divisible\n");
            else printf("Not divisible\n");
        }
    }
    
    return 0;
}

思路二(我很欽佩的一種作法):
隨機化算法,徹底看臉di

Code(別人的):

#include<cstdio>
#include<cstdlib>
using namespace std;

int a[10001];
int i,n,T,k,randomm,ans;

int main( )
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
        int tot=500,flag=0;
        while(tot)
        {
            tot--;
            ans=0;
            for(i=1;i<=n;i++)
            {
                randomm=rand(); 
                if(randomm%2)
                    ans+=a[i];
                else
                    ans-=a[i];
            }
            if(ans%k==0)
            {
                printf("Divisible\n");
                flag=1;
                break;
            }
        }
        if(!flag) printf("Not divisible\n");
    }
    return 0;
}
相關文章
相關標籤/搜索