2018.07.10【2018提高组】模拟C组

前言:

今天同时做两个比赛(B组不一定今天能改完),但是C组做完了,最后一题单独放(太难了)


题目

JZOJ 3792 分队问题

题目:

n个选手分成若干只队伍。第i个选手要求所属队伍 a [ i ] 人,满足所有要求时最多有多少只队伍。


分析

贪心,用now表示当前队伍的要求,先降序排列,每完成一个选手的要求,使now减1,当now为0时组建新的队伍,特别地,当存在队伍并在新的队伍,找到更小的要求 a i n o w = a i ,因为选手的要求越低,队伍数越多,当然在新队伍并且要求更高的可以放在前一个队伍,因为一旦有新的队伍,之前的队伍可以无限制加入选手。时间复杂度:O(n)


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
int n,a[1000001],ans,now;
int in(){
    int ans=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
}
int main(){
    n=in(); bool flag=1;
    for (int i=1;i<=n;i++) a[i]=in();
    stable_sort(a+1,a+1+n); now=a[n];
    for (int i=n;i>=1;i--){
        if (a[i]<now&&!flag) now=a[i]; now--;
        if (!now) now=a[i],ans++,flag=0;
    }
    return !printf("%d",ans);
}

JZOJ 3793 数字对

题目

数字对(a, b)可以变为(a+b, b)或(a, a+b)。最少多少次可将(1, 1)变为至少有一个数字为n的数字对。


分析

它使我想到了更相减损法, g c d ( a , b ) = g c d ( a , b a ) g c d ( a b , b ) ( a b b a )
只要计算更相减损的次数即可,但是容易超时,所以可以想到 g c d ( a , b ) = g c d ( b , a mod b )
然而, a mod b 可以表示为 a a / b b ,所以次数就是 a / b ,对于特判情况,b=0时无解,b=1时是a-1。


代码

#include <cstdio>
using namespace std;
int n,ans=233333332;
int answer(int a,int b){
    if (b==1) return a-1;
    else if (!b) return 233333333;
    else return a/b+answer(b,a%b);
}
int min(int a,int b){return (a<b)?a:b;}
int main(){
    scanf("%d",&n);
    for (int i=1;i<=(n+1)>>1;i++) ans=min(ans,answer(n,i));
    return !printf("%d",ans);
}

JZOJ 3794 高级打字机


后续

洛谷 2062 分队问题 2090 数字对 1383 高级打字机

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/80986217