1. 程式人生 > >Codeforces #499 E Border ( 裴蜀定理 )

Codeforces #499 E Border ( 裴蜀定理 )

clu 能夠 for str 末尾 cin lse border code

題目鏈接

題意 : 給出 N 種紙幣、並且給出面值、每種紙幣的數量可以任選、問你得出來的數在 k 進制下、末尾位的數有多少種可能、輸出具體方案

分析 :

紙幣任意選擇組成的和

可以用一個一次多項式來表示

A1*B1 + A2*B2 + A3*B3 + ... + An*Bn ( A 為面值、B 為數量 )

根據裴蜀定理、這個一次多項式的結果集應當是 gcd( A1、A2 .... An ) 的倍數

然後考慮怎麽得到每個數 k 進制下的最後一位數

實際上你考慮一下十進制是怎麽轉化為 k 進制的

就能夠分析出、只要將這個十進制模以 k 就能得到

那麽也就是說要求 ( A1*B1 + A2*B2 + A3*B3 + ... + An*Bn ) % k 的結果集

模可以轉化為減法 故有 A1*B1 + A2*B2 + A3*B3 + ... + An*Bn - y*k

那麽結果集就應當是 gcd( A1、A2 .... An 、k ) 的倍數

那麽總數就有 k / gcd( A1、A2 .... An 、k )

具體的方案就直接枚舉 gcd 的倍數就行了、上界為 k

技術分享圖片
#include<bits/stdc++.h>
using namespace std;

int main(void)
{
    int n, k;
    cin>>n>>k;

    int GCD = -1;
    for(int i=1
; i<=n; i++){ int tmp; cin>>tmp; if(GCD == -1) GCD = tmp; else GCD = __gcd(GCD, tmp); } GCD = __gcd(GCD, k); cout<< k / GCD <<endl; for(int i=0; i<k; i+=GCD) cout<<i<<" "; cout<<endl; return 0; }
View Code

Codeforces #499 E Border ( 裴蜀定理 )