1. 程式人生 > >牛客練習賽20(ABC)

牛客練習賽20(ABC)

分析 硬幣 ace 轉化 輸出 -- -m ram RoCE

A. 禮物

題意:

我從買奧利奧的事情中想出了一個算法題:假設某個店鋪有N種不同類型的1元奧利奧和M種不同類型的2元奧利奧,而且余量無限,我的錢有k元,我想把k元都用來買奧利奧,且可以買同類型的奧利奧,你能幫我算出有多少種購買方式嗎?設答案為Z,這個數字也許會很大,所以我們只需要輸出Z mod P的值。

分析:

計數問題,可以考慮動態規劃:每個物品可以選無數次,即無窮背包,註意無窮背包的遞推寫法。

技術分享圖片

?

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int N,M,K,P;
int d[MAXN]; int main() { int T; scanf("%d",&T); while(T--) { memset(d,0,sizeof(d)); scanf("%d%d%d%d",&N,&M,&K,&P); d[0] = 1; for(int i = 1; i <= N; i++) { for(int k = 1; k <= K; k++) d[k] = (d[k] + d[k-1
])%P; } for(int i = 1; i <= M; i++) { for(int k = 2; k <= K; k++) d[k] = (d[k] + d[k-2])%P; } printf("%d\n",d[K] ); } return 0; } ?

B. 麻婆豆腐

題意:

“咳咳...請聽題!我手上有n枚硬幣,第i枚正面朝上的概率是Pi。我現在每個硬幣各拋一次,正面朝上看做1,背面朝上看做0,把所有硬幣得到的數異或起來決定最後得到的數。問:有多少個子集合使得0和1的概率相等?” 不管音無給了怎樣的數,奏都是一分鐘不到就算出來了!不愧是前學生會長啊~ 於是他們就去食堂吃麻婆豆腐了,現在,你也來算一下吧。

分析:

可以說這個題很驚世駭俗了,當一個硬幣的概率是0.5時,它一反轉,所得異或值就會改變,而且概率相等,反之,當他的概率不是0.5時,概率必然不等,答案就轉化為有多少個集合至少含有一個0.5的硬幣,取補集,概率為0.5的硬幣是 ? ?



int main() {
    int T; scanf("%d",&T);
    for(int i = 0; i < T; i++) {
        int n;  scanf("%d",&n);
        int cnt = 0;
        double p;
        for(int i = 0; i < n; i++) {
            scanf("%lf",&p);
            if(p==0.5) cnt++;
        }
        cnt = n - cnt;
        long long ans = 1,cnts=1;
        for(int i = 0; i < n; i++)
            ans<<=1;
        for(int i = 0; i < cnt; i++)
            cnts<<=1;
        cout<<ans-cnts<<endl;
?
    }
    return 0;
}

C. 尋寶

題意:

這個迷宮由n個房間組成,編號為0到n - 1,每個房間裏都有一顆寶石,房間通過單向通道連接。每個房間裏有兩個門:一個通向第R個房間(R=(a·v2 + b·v + c) mod n),另一個通向迷宮出口,一旦離開迷宮,便會觸發自毀機關,將再也沒有機會繼續收集寶石。現在,她可以在任何地點進入迷宮,沿隧道移動並收集寶石。

分析:

因為每個點,出度均為1,點的數目 ? ,時間復雜度需要 ?

那麽圖裏面只有環,和鏈+環,這樣標記遍歷即可。

首先遍歷鏈,發現有環後,從那裏再第二次標記,這樣,環上每個結點都是環的長度。

鏈就相應要短一些。註意,訪問的時候,下面的節點已經訪問過了。

#include <bits/stdc++.h>
 
using namespace std;
 
long long a,b,c,m;
 
long long f(long long v) {
    return (a*v*v + b*v + c)%m;
}
 
int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
 
    while(T--) {
 
        scanf("%lld%lld%lld%lld",&a,&b,&c,&m);
        vector<long long> L(m,-1);
 
        for(long long i = 0; i < m; i++) {
            if(L[i]>=0) continue;
 
            long long p = i;
            long long plen = 0;
 
            while(L[p]==-1) {
                L[p] = -2;
                plen ++;
                p = f(p);
            }
 
            if(L[p]>0) {
                plen+=L[p];
            }
 
            long long clen = 0;
            while(L[p]==-2) {
                L[p] = -3;
                clen++;
                p = f(p);
            }
 
            p = i;
            while(L[p]<0) {
                if(L[p]==-3) L[p] = clen;
                if(L[p]==-2) L[p] = plen--;
                p = f(p);
            }
        }
        cout<<*max_element(L.begin(),L.end())<<endl;
    }
    return 0;
}

牛客練習賽20(ABC)