2019 ACM训练计划——( 每天5题 ) 训练计划17 【贪心好题+旋转圆+假dp】

A

Codeforces Round #292 (Div. 2), problem: © Drazil and Factorial


题目大意

让一个n位数经过函数变换后,不会出现0和1 并且尽可能是最大值,然后瞒住F ( x ) = F ( a )


题解

0 和 1 我们就不考虑了,然后根据阶乘乘积公式我们可以得到

F(4)= 3 ! * 2 ! * 2 !
F(6)=5 ! * 3 !
F(8)=7 ! * 2 ! * 2 ! * 2 !
F(9)=7 ! * 3 ! * 3 ! * 2 !
对于 2 3 5 7 我们没有办法进行划分了,就等于本身
最后将数字从大到小依次输出即可

#include<bits/stdc++.h>
using namespace std;
const int maxn=20;
int n;
char s[maxn];
int mp[maxn];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    cin>>s;
    for(int i=0;i<n;i++){
        if(s[i]=='4'){
            mp[3]+=1;
            mp[2]+=2;
        }
        else if(s[i]=='6'){
            mp[5]+=1;
            mp[3]+=1;
        }
        else if(s[i]=='8'){
            mp[7]+=1;
            mp[2]+=3;
        }
        else if(s[i]=='9'){
            mp[7]+=1;
            mp[3]+=2;
            mp[2]+=1;
        }
        else if(s[i]=='2'||s[i]=='3'||s[i]=='5'||s[i]=='7'){
            mp[s[i]-'0']+=1;
        }
    }
    for(int i=9;i>=0;i--){
        while(mp[i]>0){
            cout<<i;
            mp[i]--;
        }
    }
    cout<<endl;
    return 0;
}

B

Codeforces Round #287 (Div. 2), problem: (B) Amr and Pins


题目大意

几何题,问需要几次旋转到达新的圆心


题解

找出规律,先求两个圆心之前的距离,然后对起初圆的直径求商 看余数是否大于0 大于0就多加一次旋转

#include<bits/stdc++.h>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int r,x,y,x1,y1;
    cin>>r>>x>>y>>x1>>y1;
    double dd=pow(x1-x,2)+pow(y1-y,2);
    dd=sqrt(dd);
    double rr=2*r;
    int res=dd/rr;
    if(fmod(dd,rr)!=0)
        res+=1;
    cout<<res<<endl;
    return 0;
}

C

Codeforces Round #363 (Div. 1), problem: (A) Vacations


题目大意

一位dalao想要运动和比赛,然后又想每天进行的事情不一样
当 x = 0 的时候 不运动也不比赛
当 x = 1 的时候 不运动能比赛
当 x = 2 的时候 运动不能比赛
当 x = 3 的时候 能运动且比赛


题解

我一看这题标签 吓到了 ▄█▀█● 直接div1来一个dp 人都傻了,但一看数据n小的可怜 我就嘴角上扬45°了,然后一看题意 一想这不就是个贪心的感觉嘛 你把3当做万能牌看待 可以变成1或者2 直接遍历一遍完事了~

贪心策略:对于0就当做休息一天了 这没办法 必须休息 其它的能不休息尽量不休息 这样就能得到最小的休息天数了

#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
int a[maxn],n;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    int ans=0;
    for(int i=0;i<n;i++){
        if(a[i]==0)
            ans++;
        else if(a[i]==1){
            if(a[i+1]==3)
                a[i+1]=2;
            else if(a[i+1]==1)
            a[i+1]=0;
        }
        else if(a[i]==2){
            if(a[i+1]==3)
                a[i+1]=1;
            else if(a[i+1]==2)
                a[i+1]=0;
        }
    }
    cout<<ans<<endl;
    return 0;
}

D

Codeforces Round #303 (Div. 2), problem: © Woodcutters


题目大意

樵夫砍柴问题,砍完后可以放左边也可以放右边,但是我们不能将木头超过放置点了 所以需要考虑是放过去呢,还是不放 然后要是砍的木头尽可能的多


题解

贪心思路,要使砍下的木头尽可能多,那么对于第一根和最后一根 我们是必定砍的,那么对于中间部分的木头 我们优先往左放 实在不行的话就判断右方 然后将当前的起始点更新

不过对于n==1的情况 需特殊处理一下 是必定砍下这棵树 所以能得到1根木头

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,idx[maxn],loc[maxn];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>idx[i]>>loc[i];
    int cnt=2;
    for(int i=1;i<n-1;i++){
        if(idx[i]-idx[i-1]>loc[i])
            cnt++;
        else if(idx[i+1]-idx[i]>loc[i]){
            cnt++;
            idx[i]+=loc[i];
        }
    }
    n==1? cout<<1<<endl: cout<<cnt<<endl;
    return 0;
}

E

Codeforces Round #322 (Div. 2), problem: (A) Vasya the Hipster


题目大意

有红蓝两种袜子,dalao想赶时髦,优先会穿红色和蓝色的袜子,需要注意,当天穿完后,会扔掉穿过的袜子,然后穿同一款颜色的袜子 问穿不同袜子的天数和穿相同袜子的天数


题解

水题。先求红蓝袜子的最小值 即为穿不同袜子的天数,然后在剩余袜子除以2 加起来即为穿相同袜子的天数

#include<bits/stdc++.h>
using namespace std;
int a,b;
int main(){
    cin>>a>>b;
    int cc=min(a,b);
    a-=cc,b-=cc;
    int dd=a/2+b/2;
    cout<<cc<<" "<<dd<<endl;
    return 0;
}
学如逆水行舟,不进则退
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一百个Chocolate

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值