寒假訓練賽第五場

問題 A: 分火腿

題目描述

小月⾔要過四歲⽣日了,她的媽媽爲她準備了n根⽕腿,她想將這些⽕腿均分給m位小朋友,所以她可能需要切⽕腿。爲了省事,小月⾔想切最少的⼑數,使這n根⽕腿分成均等的m份。請問最少要切⼏⼑?

輸入

第⼀⾏⼀個整數T,表示有T組數據。
接下來T組數據,每組共⼀⾏,有兩個數字n,m。

輸出

每組數據⼀⾏,輸出最少要切的⼑數。

樣例輸入 Copy

2
2 6
6 2

樣例輸出 Copy

4
0

思路
一開始題目沒說2根香腸分3份只要切2刀,wa了,後來考慮了這種情況,找規律可得解;

ll gcd(ll a,ll b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}

int main()
{
    int n;cin>>n;
    while(n--)
    {
        ll x,y;
        cin>>x>>y;
        if(y==0||x%y==0) cout<<0<<endl;
        else if(y%x==0)
        {
            ll z=y/gcd(x,y);
            cout<<(z-1)*x<<endl;
        }
        else
            cout<<y-gcd(x,y)<<endl;
    }
    return 0;
}

問題 B: 工資

題目描述

n+e在暑假參加了打零⼯的活動,這個活動分爲n個⼯作日,每個⼯作日的⼯資爲Vi。有m個結算⼯錢的時間,n+e可以自由安排這些時間,也就是說什麼時候拿錢,老闆說的不算,n+e纔有發⾔權!(因爲n+e是⼟豪,他是老闆的老闆)
n+e不喜歡身上⼀次性有太多的錢,於是他想安排⼀下拿錢的時間,使他⼀次性拿的錢中最⼤的那次的最小。(最後⼀天⼀定要領錢)

輸入

第⼀⾏2個數n,m
接下來n⾏,每⾏⼀個數,代表Vi

輸出

輸出⼀⾏⼀個整數,表示最小的最⼤錢數。

樣例輸入 Copy

7 5
100
400
300
100
500
101
400

樣例輸出 Copy

500

提示

100 400//300 100//500//101//400// ”//” 表示 n+e 要去拿錢。

對於20%的數據,1<=n<=20
對於另20%的數據,1≤n≤50,Vi的和不超過1000
對於100%的數據,1≤n≤100000,m≤n,Vi≤100000

思路
二分答案ans,判斷mid是否符合judge函數的判斷,符合判斷則滿足分組要求,可以將 r 減小,否則將 l 增大。

int n,m;
ll a[100005];///用long long

bool judge(ll mid)
{
    int cnt=0;
    ll ret=0;
    for(int i=1;i<=n;i++)
    {
        if(ret+a[i]>mid)
        {
            ret=a[i];
            cnt++;
        }
        else ret+=a[i];
        if(cnt>=m || ret>mid)///有多於m個分組是大於mid的,則非法
            return false;    ///或者是其中一個數ret大於mid,也非法
    }
    if(cnt<m) return true;
    return false;
}

int main()
{
    cin>>n>>m;
    ll ans,minn=1000000,maxn=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        maxn+=a[i];
        minn=min(minn,a[i]);
    }
    while(minn<maxn)
    {
        ll mid=(minn+maxn)/2;
        if(judge(mid)) maxn=mid;
        else minn=mid+1;

    }
    cout<<minn<<endl;
}

問題 C: 公約數

題目描述

話說CD比較⽋扁,他表示在課室的日⼦沒有教主在旁邊打他的日⼦太寂寞了,所以這⼀晚,他終於來到了電腦室被打。由於CD是⼤家的寵物,於是⼤家都來打CD了。
電腦室裏有n個⼈,第i個⼈希望打CD ai下。但是太多⼈打CD,他又會不爽,於是他規定只能有K個⼈打到他,並且爲了公平起見,最終K個⼈打他的次數都必須是相同的,CD規定這個次數就是這K個⼈希望打他的次數的最⼤公約數。爲什麼是最⼤公約數呢?因爲他覺得被打的次數是GCD的話他纔會變成Glad CD。
之前說了,CD比較⽋扁,於是CD希望,K個⼈打他的次數的和最⼤。你能告訴他他最後總共會被打多少下麼?

輸入

第⼀⾏兩個正整數n,k。
第⼆⾏n個正整數,表示每個⼈希望打CD多少下。

輸出

輸出⼀個正整數表示CD會被打多少下。

樣例輸入 Copy

3 1
1 2 3

樣例輸出 Copy

3

提示

對於30%的數據,保證k≤n≤20。
對於50%的數據,保證輸⼊中所有數小於5000。
對於100%的數據,保證輸⼊中所有數小於500000,k≤n。

思路:暴力枚舉: i 從a[i]_max開始枚舉到1,查詢是否有大於等於k個數數是i的倍數,若有,則i是最大公約數。

int n;
ll k;
int visit[500005];
int main()
{
    cin>>n>>k;
    int maxn=0;
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);visit[x]++;
        maxn=max(maxn,x);
    }
    for(int i=maxn;i>=1;i--)
    {
        int cnt=0;
        for(int j=i;j<=maxn;j+=i)///查詢是否存在i的倍數
        {
            if(visit[j])cnt+=visit[j];///存在,則計算有多少個
            if(cnt>=k) break;
        }
        if(cnt>=k)
        {
            printf("%lld",i*k);///cout會出錯
            break;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章