2022.1.19

上午补周测题

下午补周测题,先中序求后序题

晚上 还是先中序求后序题,后中序求前序

题目描述

在一个一维世界中,有nn平台。带索引的平台kk(平台从 1 开始编号)是带有坐标的段[(k-1)米,(k-1)米+升][(k−1)m,(k−1)+l]和l<ml<m.蚱蜢鲍勃开始从点沿着平台跳跃00,每次跳跃时,他都会精确地移动dd单位正确。找出点的坐标,鲍勃将在哪里摔倒。蚱蜢掉下来,如果他发现自己不在平台上,但如果他发现自己在平台的边缘,他就不会掉下来。

输入格式

第一个输入行包含 4 个整数nn,dd,mm,ll ( 1<=n,d,m,l<=10^{6},l<m1<=ndm,l<=106,l<m) — 分别:平台数量、蚱蜢 Bob 跳跃的长度和数字mm和ll需要查找的坐标kk-第四个平台:[(k-1)米,(k-1)米+升][(k−1)m,(k−1)+l].

输出格式

输出点的坐标,粗心跳汰机将落在该点的位置。不要忘记,如果鲍勃发现自己在平台边缘,他不会摔倒。

题意翻译

题目描述:在一坐标轴上给出n块板子,每个板子所占的空间为[(k-1)m,(k-1)m+l](l<m),一个青蛙从原点0起跳,每次跳d距离远,问最后青蛙会落在哪里(没落在板子上就结束跳跃) 输入:一行四个整数n,d,m,l 输出:一个整数,即青蛙最后的落点 1<=n,d,m,l<=10^6 l<m

Translated by 稀神探女

输入输出样例

输入 #1复制
2 2 5 3
输出 #1复制
4
输入 #2复制
5 4 11 8
输出 #2复制
20

 要么跳在板子上,要么没落在板子上,所以只需要知道在这块板子上的最远的地方((i-1)*m+l)/d)*d再跳一下,看它是否能跳在后面的板子上。

#include<stdio.h>

int main()
{
    long long n,d,m,l,s=0,i;
    scanf("%lld%lld%lld%lld",&n,&d,&m,&l);
    for(i=1;i<=n;i++){
        if(s<(i-1)*m){//跳到缝隙里了,结束
            break;
        }
        s=(((i-1)*m+l)/d)*d+d;//在第i块板子上最远距离+d
    }
    printf("%lld\n",s);
}

题意翻译

题意描述

关于 Codeforces 的网站 king Copa 经常被报道,使得它在要使用网站进行训练和比赛的人之间迅速流行开来。最近, Copa 明白,要征服世界,他需要组织世界 Codeforces 锦标赛。他希望在这次比赛之后之后,最聪明的人将成为被挑选出来成为他的下属,然后征服世界最艰难的部分将会完成。

Codeforces 世界总决赛的最后一轮定于 YYYY 年 MMMM 月 DDDD 日举行,其中 DDDD 是当天的日期, MMMM 是当月的月份, YYYY 是当年的年份的最后两位。Bob 很幸运地能成为来自 Berland 的一名决赛选手。但有一个问题:根据比赛规则,所有参赛者在决赛时必须年满 1818 岁。 Bob 出生于 BYBY 年, BMBM 月,BDBD 日。这个日期记录在他的护照上,他的护照复印件已经寄给了组织者。但是 Bob 了解到,在不同的国家,日期的书写方式是不同的。例如,在美国,先写月份,然后写日期,最后写年份。

鲍勃想知道是否有可能重新排列他出生日期的数字,以便他在 YYYY 年, MMMM 月, DDDD 日那天至少 1818 岁。他看出,在他的祖国,日期写的顺序不一样。请帮帮他。 根据另一个奇怪的规则,合格的参赛者必须与决赛日期出生在同一个世纪。如果决赛当天刚好是参赛者的 1818 岁生日,则他可以参加。

因为我们只考虑从 20012001 年到 20992099 年的决赛年份,所以使用以下规则:如果年份的数字可以被 44 整除,那么年份就是闰年。

输入格式:

第一行包括三个数字 DD,MM,YYDD,MM,YY ,第二行包括三个数字 BD,BM,BYBD,BM,BY ,数据保证两个日期的正确性,并且 BYBY 和 YYYY 保证在 [ 01 ,99 ][01,99] 中。

输出格式:

如果可能通过重新排列出生日期的顺序,让 Bob 在比赛当天至少 1818 岁,则输出 YES 。如果不能,则输出 NO。

输入输出样例

输入 #1复制

01.01.98
01.01.80

输出 #1复制

YES

输入 #2复制

20.10.20
10.02.30

输出 #2复制

NO

输入 #3复制

28.02.74
28.02.64

输出 #3复制

NO

将每一项都列出来,判断符不符合要求

#include<stdio.h>

int DD,MM,YY;
int Mon[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};

int M(int d,int m,int y)
{
    if(d>Mon[m]||d<1||m>12||m<1) return 0;//年月日越界不可行
    if(y%4!=0&&m==2&&d>28) return 0;//平年2月越界
    if((y+18)<YY||y+18==YY&&m<MM||y+18==YY&&m==MM&&d<=DD) return 1;//达到年龄要求
    else return 0;
}

int main()
{
    int BD,BM,BY;
    scanf("%d.%d.%d",&DD,&MM,&YY);
    scanf("%d.%d.%d",&BD,&BM,&BY);

    if(M(BD,BM,BY)||M(BD,BY,BM)||M(BM,BD,BY)||M(BM,BY,BD)||M(BY,BD,BM)||M(BY,BM,BD))//有一项符合就行
        printf("YES\n");
    else printf("NO\n");
}

题目描述

农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。

你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。(你可能已经知道你可以在知道树的两 种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。 这是在样例输入和 样例输出中的树的图形表达方式:

         C
         /  \
        /  \
       B    G
      / \  /
       A   D  H
        / \
       E   F

树的中序遍历是按照左子树,根,右子树的顺序访问节点。

树的前序遍历是按照根,左子树,右子树的顺序访问节点。

树的后序遍历是按照左子树,右子树,根的顺序访问节点。

输入格式

第一行: 树的中序遍历

第二行: 同样的树的前序遍历

输出格式

单独的一行表示该树的后序遍历。

输入输出样例

输入 #1复制

ABEDFCHG
CBADEFGH 

输出 #1复制

AEFDBHGC

说明/提示

题目翻译来自NOCOW。

USACO Training Section 3.4

 

前序遍历是根左右,中序是左根右,先从前序开始,前序遍历的第一个就是根节点,然后遍历中序找到它的位置,中序中它左边的字母就是根节点的左子树,右边就是右子树,再把左边的看成是一个树,遍历的第一个就是根节点的左孩,又可以从中序中找到左右子树...右边也看成一个树,遍历的第一个就是根节点的右孩...就可以用递归实现建一个二叉树(讲道理一开始好像懂了也不知道咋个用递归实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char f[100],m[100];

typedef struct Tree
{
    char data;
    struct Tree *lc,*rc;//左孩,右孩
}tree;

tree *M(int l,int r,int l2,int r2,tree *T)
{
    if(l>r||l2>r2) return NULL;
    T=(tree *)malloc(sizeof(tree));
    T->data=f[l];//前序遍历的第一个字母就是根节点
    if(l2==r2){//只有这一个字母,它就是叶节点
        T->lc=NULL;
        T->rc=NULL;
        return T;
    }
    int s=0;
    for(int i=l2;i<=r2;i++){
        if(m[i]==f[l]) break;
        else s++;
    }
    T->lc=M(l+1,l+s,l2,l2+s-1,T->lc);//递归左子树
    T->rc=M(l+s+1,r,l2+s+1,r2,T->rc);//递归右子树
    return T;
}

void Posttree(tree *T)//后序遍历
{
    if(T==NULL) return;
    Posttree(T->lc);
    Posttree(T->rc);
    printf("%c",T->data);
}

int main()
{
    tree *T;
  //  gets(m);//中序
    //gets(f);//前序
    scanf("%s",m);
    scanf("%s",f);
    int str=strlen(m);
    T=M(0,str-1,0,str-1,T);
    Posttree(T);
    printf("\n");
}

 

 

题目描述

给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度\le 8≤8)。

输入格式

22行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。

输出格式

11行,表示一棵二叉树的先序。

输入输出样例

输入 #1复制

BADC
BDCA

输出 #1复制

ABCD

说明/提示

【题目来源】

NOIP 2001 普及组第三题

 这个和前面的那题差不多,后序的话是左右根,从最后面开始第一个是根节点,然后还是从中序中分成左右子树..

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char m[100],p[100];

typedef struct Node
{
    char data;
    struct Node *lc,*rc;
}tree;


tree *M(int l,int r,int l2,int r2,tree *T)
{
    if(l>r||l2>r2) return NULL;
    T=(tree *)malloc(sizeof(tree));
    T->data=p[r];
    if(l2==r2){
        T->lc=NULL;
        T->rc=NULL;
        return T;
    }
    int s=0,b;
    for(int i=l2;i<=r2;i++){
        if(m[i]==p[r]) {b=i;break;}
        else s++;
    }
    T->lc=M(l,l+s-1,l2,l2+s-1,T->lc);
    T->rc=M(l+s,r-1,l2+s+1,r2,T->rc);
    return T;
}

void Pretree(tree *T)//前序遍历
{
    if(T==NULL) return;
    printf("%c",T->data);
    Pretree(T->lc);
    Pretree(T->rc);
}

int main()
{
    tree *T;
    scanf("%s",m);
    scanf("%s",p);
    int str=strlen(m);
    T=M(0,str-1,0,str-1,T);
    Pretree(T);
    printf("\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值