[随便切水题系列]hihoCoder太阁算法竞赛12

今天晚上感觉情绪莫名的低落,openGL渲染一个小图搞了半天没搞好,还有一大堆的作业实验报告,还有比赛和考试要准备,感觉很烦,所以上hihocoder上敲了一点水题,让心情放松下来。一直不能掌控自己的情绪,总是容易被各种环境因素带节奏。根本原因还是自己弱的不行啊。
题目链接:https://hihocoder.com/contest/hihointerview21/problems

A题

给出4个数,求这4个数可以构造出来的最大时钟时间。
只有4个数,直接按字典序枚举这4个数的所有排列,判断是否可以构成一个时钟时间即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<iterator>
#include<algorithm>
using namespace std;

int a[4],ans[4];
bool flag;

//judge if the time is legal
bool Judge(int* arr)
{
    if(arr[0]>2)return false;
    else if(arr[0]<=1)return a[2]<6;
    else{
        return a[1]<4&&a[2]<6;
    }
}

int main()
{
    flag = false;
    int x = 0;
    for(int i=0;i<4;i++)
        scanf("%d",&a[i]);

    sort(a,a+4);
    do{
        x++;
        if(Judge(a)){
            flag = true;
            memcpy(ans,a,sizeof(a));
        }
    }while(next_permutation(a,a+4));

    //cout << x << endl;
    if(!flag)
        printf("NOT POSSIBLE\n");
    else
        printf("%d%d:%d%d\n",ans[0],ans[1],ans[2],ans[3]);
    return 0;
}

B题

求最短的需要排序的子序列的长度
很显然,如果一个数比其前面的所有的数都要大,表现出来,就是比其前面最大的数还要大,那么这个数就不需要改变其与前面的数的相对位置。如果比其前面最大的数小,那么很显然需要交换,直接2分搜索找到其要交换的初始位置st[i],以当前位置为en[i].那么本题的答案就是

max{en[i]}min{st[i]}

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

#define MAXN 100005

int curn,curmax,st,en,n;
int Arr[MAXN];

int binSearch(int s,int t,int tar)
{
    int ans = 0;
    while(s<=t){
        int mid = (s+t)/2;
        if(Arr[mid]>tar)t=mid-1;
        else{
            ans = mid;
            s = mid+1;
        }
    }
    return ans;
}

int main()
{
    freopen("input","r",stdin);
    int i;
    scanf("%d",&n);
    scanf("%d",&curmax);
    Arr[0]=curmax;
    st=en=-1;

    for(i=1;i<n;i++){
        scanf("%d",&Arr[i]);
        if(Arr[i]>=curmax){
            curmax = Arr[i];
            continue;
        }
        else{
            if(st<0)st=binSearch(0,i-1,Arr[i]);
            en = i;
        }
    }
    printf("%d\n",en-st);
    return 0;
}

C题

有点意思的一道题,一个数可以使用二进制表示,现在允许二进制的系数为0,-1,1,问最少需要多少个二进制系数不为0.
发现了下面的公式:

n=in=j2n=2j+12i

其实就是等比数列求和公式的应用,那么就很简单了,记录当前时刻连续的二进制表示的1的数量,要注意的是此时产生了一个新的高位二进制1还有可能和其他的数聚合,代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

#define LL unsigned long long

LL n;
int curo;
int ans=0;

int main()
{
    int bit;
    scanf("%lld",&n);
    curo=0;

    while(n){
    //  cout << ans << endl;
        bit = n&1;
        if(bit)curo++;
        else{
            ans += min(curo,1);
            if(curo==1){
                curo=0;
            }
            else if(curo>=2){
                curo=1;
            }
            else{}
        }
        n/=2;
        //cout << curo << endl;
    }
    ans += min(2,curo);
    printf("%d\n",ans);
    return 0;
}

最后一点:淡定,从容,掌控情绪。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值