刷题刷题,开心

一先来每日一题

在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]。

请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。 你可以返回任何满足该要求的答案,此题保证存在答案。

示例 1:

输入:barcodes = [1,1,1,2,2,2]
输出:[2,1,2,1,2,1]
示例 2:

输入:barcodes = [1,1,1,1,2,2,3,3]
输出:[1,3,1,3,2,1,2,1]
 

提示:

1 <= barcodes.length <= 10000
1 <= barcodes[i] <= 10000
通过次数20,401提交次数46,900

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/distant-barcodes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这题目,要的就是对堆的排序,对出现的数进行统计

转化成堆

我们应当把最多的最先排,排了一个后更新堆,再拿最多的,但是要判断和上一 个是不是一样的

如果一样的,我们就取第二多的来排,每次排完之后要更新,堆

我们建堆,不需要建立啥完整的东西,我们只需要一个上滤或者下滤,因为不需要出堆,堆形成后不会有任何的增加或者减少

所以工作量不大,还是可以接受的

代码

typedef struct node{
    int num;
    int size;
}squrt;

squrt dui[100100];
int duisize=1;

void down(int x){//下滤
    if(x*2<duisize)
     if(dui[x].size<dui[2*x].size){
           squrt k=dui[x];
           dui[x]=dui[2*x];
           dui[2*x]=k;
           down(2*x);
     }
     if(x*2+1<duisize)
       if(dui[x].size<dui[2*x+1].size){
           squrt k=dui[x];
           dui[x]=dui[2*x+1];
           dui[2*x+1]=k;
           down(2*x+1);
     }
}
//向下滤

int* rearrangeBarcodes(int* barcodes, int barcodesSize, int* returnSize){
int a[100100]={0};
int map[100100]={0};
*returnSize=barcodesSize;
int* ans=(int*)malloc(sizeof(int)*100100);
for(int j=0;j<barcodesSize;j++){ 
    a[barcodes[j]]++;
}
 
 for(int j=0;j<barcodesSize;j++){
     if(a[barcodes[j]]!=0&&map[barcodes[j]]==0){
         map[barcodes[j]]=1;
         dui[duisize].num=barcodes[j];
         dui[duisize].size=a[barcodes[j]];
         duisize++;
     }
 }//统计

 for(int j=duisize-1;j>=1;j--){
        if(j<=duisize/2){
            down(j);
        }
 }//下滤建堆

ans[0]=dui[1].num;
dui[1].size--;
down(1);


for(int m=1;m<barcodesSize;m++){
    if(ans[m-1]!=dui[1].num){
        ans[m]=dui[1].num;
        dui[1].size--;
        down(1);
    }
    else{//第二的肯定是堆顶的右儿子或者是左儿子
         if(dui[2].size>=dui[3].size){
               ans[m]=dui[2].num;
               dui[2].size--;
                down(2);
         }   
         else{
               ans[m]=dui[3].num;
               dui[3].size--;
                down(3);
         }
    }
}


return ans;
}

 

小孩爱吃糖

Description

幼儿园里面有n 个孩子,老师让这n个孩子站成一排。

定义一个整数数组 a[n]表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。

相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

Input

第一个行输入一个n,代表有n个孩子(1 <= n <= 2 * 10^4)

第二行输入n个数,表示每个孩子的评分(0 <= a[i] <= 2 * 10^4)
 

Output

输出仅一行,表示需要准备的 最少糖果数目

Sample Input 1 

3
1 0 2

Sample Output 1

5

Sample Input 2 

3
1 2 2

Sample Output 2

4

Hint

对于第一个样例,你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

对于第二个样例,你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。

这题目,思路想想还是简单的,

我们可以得到信息,我要是比左边的大我得到的糖果至少比他大一

我要死是比右边的大我得到的糖果就比他大一

那我们从左边来遍历一遍,这个比前面的大就是他加1(最少)

从右边也来一次

就可以了

把数组相加,就可以得到答案了

#include<stdio.h>

int main(){
int n;
int a[10000];
int ans[10000];
ans[1]=1;
scanf("%d",&n);

for(int j=1;j<=n;j++){
    scanf("%d",&a[j]);
}

for(int j=2;j<=n;j++){
    if(a[j]>a[j-1]){
        ans[j]=ans[j-1]+1;
    }
    else{
        ans[j]=1;
    }
}
for(int k=n-1;k>=1;k--){
    if(a[k]>a[k+1]){
        ans[k]=ans[k+1]+1;
    }
}

int sum=0;
for(int k=n;k>=1;k--)
    sum+=ans[k];

printf("%d",sum);

}

这是二叉搜索树吗?

Description

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

Input

输入的第一行给出正整数N(≤1000)。随后一行给出N个整数键值,其间以空格分隔。

Output

如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出YES,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出NO

Sample Input 1 

7
8 6 5 7 10 8 11

Sample Output 1

YES
5 7 6 8 11 10 8

Sample Input 2 

7
8 6 8 5 10 9 11

Sample Output 2

NO

注意,如果是镜像树的话是输出镜像树的后序遍历

判断是不是二叉搜索树的方法就是,左子树比我小右子树比我大

7

8 6 5 7 10 8 11

如上 

6 5 7 比8 小就是左树 10 大于8其和其后面的就是右子树\

不能成树的情况就是 8 6 5 7 10 7 11 第一个比根大的点后面还有比根小的

这不符合 右子树都比根大的定义

镜像就是反过来,就是定义也反了,判断和上面是一样的

在判断遍历的时候,可把节点压入栈中,遍历完确定性质符合就可以直接输出

但是压入的方式 要注意确保输出的是后序(自己给自己增加了难度,,,,)

两种树只要符合其中的一种就可以了

代码

#include<stdio.h>
#include<stdlib.h>
int a[10010] = { 0 };
int rsl = 1;
int dsl = 1;//刚开始都认为是正确的
int n;

typedef struct node {
    int a;
    struct node* l;
    struct node* r;

}Node;
typedef struct {
    Node* root;
}Tree;

typedef struct sq {
    int data[1010];
    int length;
}sqt;//栈输出后序的辅助结构

void push(int e, sqt& s) {
    s.data[s.length] = e;
    s.length++;
}

int pop(sqt& s) {
    if (s.length > 0) {
        s.length--;
        return s.data[s.length];
    }
    else {
        return -1;
    }
}

void pan1(int p, int l, int r, sqt& s1) {
    int kl = 0;

    int rs = r + 1;//右子树的根节点


    for (int h = l;h <= r;h++) {
        if (a[h] >= p && kl == 0) {
            rs = h;
            push(a[rs], s1);
            kl = 1;
        }
        if (kl == 1 && a[h] < p) {
            rsl = 0;
            return;
        }
    }
    int ls; //左边
    if (a[l] < p) {
        ls = l;
    }
    else {
        ls = r + 1;
    }
    if (rs + 1 <= r) {
        pan1(a[rs], rs + 1, r, s1);
    }

    if (ls == l) {
        push(a[ls], s1);
    }

    if (ls + 1 <= rs - 1) {
        pan1(a[ls], ls + 1, rs - 1, s1);
    }



}
void pan2(int p, int l, int r, sqt& s2) {
    int kl = 0;
    int ls;//左子树的根节点
    int rs = r + 1;//右子树的根节点



    for (int h = l;h <= r;h++) {
        if (a[h] < p && kl == 0) {
            rs = h;
            push(a[rs], s2);
            kl = 1;
        }
        if (kl == 1 && a[h] >= p) {
            dsl = 0;
            return;
        }
    }
    if (a[l] >= p) {
        ls = l;
    }
    else {
        ls = r + 1;
    }


    if (rs + 1 <= r) {
        pan2(a[rs], rs + 1, r, s2);
    }


    if (ls == l) {
        push(a[ls], s2);
    }

    if (ls + 1 <= rs - 1) {
        pan2(a[ls], ls + 1, rs - 1, s2);
    }
}



int main() {

    scanf("%d", &n);
    for (int j = 1;j <= n;j++)
        scanf("%d", &a[j]);
    sqt s1, s2;
    s1.length = 0;
    s2.length = 0;
    push(a[1], s1);
    push(a[1], s2);
    pan1(a[1], 2, n, s1);
    pan2(a[1], 2, n, s2);
    if (rsl == 1 || dsl == 1) {
        printf("YES\n");
        if (rsl == 1) {

            while (s1.length != 0) {
                int j = pop(s1);
                printf("%d", j);
                if (s1.length != 0) {
                    printf(" ");
                }
            }
        }
        else if (dsl == 1) {

            while (s2.length != 0) {
                int j = pop(s2);
                printf("%d", j);
                if (s2.length != 0) {
                    printf(" ");
                }
            }
        }
    }
    else {
        printf("NO");
    }
    return 0;
}

最好可以在本子上面画画看看到底压入栈是咋搞的,便于理解如果是选择建树来输出的话,可能比这要简单易懂的多 

洛希极限

Description

科幻电影《流浪地球》中一个重要的情节是地球距离木星太近时,大气开始被木星吸走,而随着不断接近地木“刚体洛希极限”,地球面临被彻底撕碎的危险。但实际上,这个计算是错误的。

洛希极限(Roche limit)是一个天体自身的引力与第二个天体造成的潮汐力相等时的距离。当两个天体的距离少于洛希极限,天体就会倾向碎散,继而成为第二个天体的环。它以首位计算这个极限的人爱德华·洛希命名。(摘自百度百科)

大天体密度与小天体的密度的比值开 3 次方后,再乘以大天体的半径以及一个倍数(流体对应的倍数是 2.455,刚体对应的倍数是 1.26),就是洛希极限的值。例如木星与地球的密度比值开 3 次方是 0.622,如果假设地球是流体,那么洛希极限就是0.622×2.455=1.52701倍木星半径;但地球是刚体,对应的洛希极限是0.622×1.26=0.78372倍木星半径,这个距离比木星半径小,即只有当地球位于木星内部的时候才会被撕碎,换言之,就是地球不可能被撕碎。

本题就请你判断一个小天体会不会被一个大天体撕碎。

Input

输入在一行中给出 3 个数字,依次为:大天体密度与小天体的密度的比值开 3 次方后计算出的值(≤1)、小天体的属性(0 表示流体、1 表示刚体)、两个天体的距离与大天体半径的比值(>1但不超过 10)。

Output

在一行中首先输出小天体的洛希极限与大天体半径的比值(输出小数点后2位);随后空一格;最后输出^_^如果小天体不会被撕碎,否则输出T_T

Sample Input 1 

0.622 0 1.4

Sample Output 1

1.53 T_T

Sample Input 2 

0.622 1 1.4

Sample Output 2

0.78 ^_^

好啊

妥妥的水题(呜呜呜呜呜)

上代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>



int main(){
double ll=0,kk=0,oo=1.26;
int jj=0;
scanf("%lf",&ll);

scanf("%d",&jj);

scanf("%lf",&kk);


if(jj==0)
oo=2.455;

double ans=ll*oo;


printf("%0.2lf",ans);
if(ans<kk){
    printf("^_^");
}
else{
    printf("T_T");
}


return 0;
}

ok,我还有题目要理解一下,关于动态线段树的理解

以及背包,我还没完全吃透讲不出来

让我给它研究一会再讲

还有,我要学c++,每次打数据结构要打好久啊

痛真的太痛了

ok撒花谢幕

bb

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值