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

来源:互联网 发布:淘宝上那个吉他店最好 编辑:程序博客网 时间:2024/04/29 20:16

今天晚上感觉情绪莫名的低落,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 legalbool 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 100005int 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 longLL 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
原创粉丝点击