牛客練習賽117 C&D

Link

C 分類討論貪心
顯然的,正面考慮怎麼拼團會很麻煩,所以我們從另一個視角考慮,求出可能的最大團數,然後看一看怎麼踢人能夠使落單的最少。
當K爲偶數的時候,顯然最大團數就是\((n+m*2)/k\),而當K爲奇數的時候,顯然男生抱團需要至少一個男生,女生抱團也需要至少一個男生,最大團數就是\(min(n,(n+m*2)/k)\),然後進一步考慮
顯然女生因爲價值高,讓她落單應該優先。

#include<iostream>
#include<cstdio>
using namespace std;
int t;
long long n,m,k;
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%lld%lld%lld",&n,&m,&k);
            int d=min(n,(n+m*2)/k);
            if(k%2==0) d=(n+m*2)/k;
            int res=n+m*2-d*k;
            if(res<=m*2) printf("%lld\n",res/2+res%2);
            else printf("%lld\n",res-m*2+m);
    }
    return 0;
}

D
如果最後變成了反面朝上,顯然的是所有的硬幣都被操作了奇數次。
所以當k爲奇數的時候,顯然可以,只要每個硬幣開頭搞一次就可以了。
當K爲偶數的時候,如果n爲奇數,顯然任意次操作後反面朝上的硬幣爲偶數個,不合題意。
如果n也是偶數,那麼可以把相鄰的硬幣看作是一個大硬幣,轉換成小問題。

#include<cstdio>
#include<iostream>
using namespace std;
int t;
int n,k;
int gcd(int a,int b){
    if(b==0) return a;
    else return gcd(b,a%b);
}
void deal(){
    if(k&1){
        printf("%d\n",n);
        for(int i=1;i<=n;++i)
            printf("%d ",i);
        printf("\n");
    }else{
        if((n&1)){
            printf("-1\n");
        }else{
            int tem=gcd(n,k);
            if((k/tem)%2==0){
                printf("-1\n");
            }else{
                printf("%d\n",n/tem);
                for(int i=1;i<=n;i+=tem)
                    printf("%d ",i);
                printf("\n");
            }
        }
    }
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        deal();
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章