Recall2019BNUOJ

Posted leisureeen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Recall2019BNUOJ相关的知识,希望对你有一定的参考价值。

2019年本人在北京师范大学OJ系统上做了一些题目,现在回忆出来(代码不需要回忆,有记录,目前共8题)。

Primary Arithmetic

pid=1006

当你在小学学习算数的时候,老师会教你把两个数由右至左按位加起来。很多时候,加法过程中会出现进位。对于一部分孩子,理解这个“进位”在当时是很困难的事情。现在你的工作就是编写一个程序来判断两个数相加的过程中会产生多少次进位,用以确定这两个数相加的“难度”。

Input

每一行有两个无符号整数(最大不超过1000000000),当输入0 0的时候,程序结束。
 

Output

对于每一行的输入两个整数,你需要判断会产生有多少个进位,每一个输出占一行。
 

Sample Input

123 456
555 555
123 594
0 0

Sample Output

No carry operation.
3 carry operations.
1 carry operation.

Source

 
#include<stdio.h>

int main(void)
{
    int a=0,b=0;
    while(scanf("%d%d",&a,&b),a|b)
    {
        int n=0,cf=0;
        for(;a|b;a/=10,b/=10)
            if(a%10+b%10+cf>9)
                n++,cf=1;
            else
                cf=0;
        if(n)
            printf("%d",n);
        else
            printf("No");
        printf(" carry operation");
        if(n>1)
            putchar(s);
        puts(".");
    }
    return 0;
}

 

 

最少比较次数

 pid=1034
排序是计算机程序设计中最常用的操作之一,通常都是通过比较操作来完成排序。我们知道,要对一组整数进行排序,只要把它们两两进行一次比较,肯定能够完成。但是,其实这么多次比较并不都是必要的,例如,对A、B、C三个数进行排序,如果通过比较得到A>B、B>C,那么A和C之间的比较就是完全没有必要的了。
所以,我们常常只需要一部分比较结果,就能完成排序操作。
现在有n个整数,请问如果采用最佳的比较策略,至少需要多少次比较操作才能保证完成排序呢?

Input

输入包括多组数据,每组数据为一个整数n(1≤ n ≤ 5),表示需要排序的整数的个数。
如果n = 0则表示输入结束。

Output

输入包括多组数据,每组数据为一个整数n(1≤ n ≤ 5),表示需要排序的整数的个数。
如果n = 0则表示输入结束。
 

Sample Input

3
0

Sample Output

3

Hint

对于3个数排序,如果通过两次比较得到A>B、B>C,则不需要第三次比较,但是如果得到的是A>B、B<C,这A、C之间还需要一次比较。所以3个数的时候至少需要3次比较才能保证完成排序操作。
 

Source

Author

LiuLibo
 
 
#include<stdio.h>

int main(void)
{
    int n=0,key[]={0,1,3,5,7};
    while(1)
    {
        scanf("%d",&n);
        if(!n)
            break;
        printf("%d
",key[n-1]);
    }
    return 0;
}

 

转义字符

pid=1041

printf是C语言中最常用的输出函数。为了输出一些特殊字符,printf中定义了一些转义字符,但是如果想要输出这些转义字符,又需要将这些转义字符转义(囧RZ,好晕)。如果我们想输出下面这个字符串:
"ab%d
我们不能使用
printf(""ab%d");
输出上面的字符串,而应该改写为
printf("\"ab%%d");
根据经验,我们发现在我们使用的字符串中有下面几种字符需要被改写:

  1. 需要被改写为\
  2. "需要被改写为"
  3. %需要被改写为%%

给出串s,请输出按上述规则将s改写后所得的新串。

 

Input

输入第一行为一个整数n(0<n<=40),表示有n个串需要被改写。
接下来是n行,每一行为一个串s。s可能由字母、数字以及各种可见符号构成。s的长度不超100。

 

Output

对每一个串s,输出一行,为将s改写后的结果。

 

Sample Input

2
abc.
"ab%.3d

Sample Output

abc.
\"ab%%.3d

Source

 

#include<stdio.h>

int main(void)
{
    int n=0;
    char s[101]="",res[201]="",*p1=s,*p2=res;
    scanf("%d%*c",&n);
    while(n--)
    {
        gets(s);
        for(p1=s,p2=res;*p1;p1++)
        {
            if(*p1==%)
                *p2++=%,*p2++=%;
            else if(*p1==\)
                *p2++=\,*p2++=\;
            else if(*p1==")
                *p2++=\,*p2++=";
            else
                *p2++=*p1;
        }
        *p2=;
        puts(res);
    }
    return 0;
}

 

 

Hanoi

 pid=17118

汉诺塔问题基本上是学习递归必举的例子,如果您对于Hanoi问题不熟悉,请移步这里http://zh.wikipedia.org/zh-cn/%E6%B1%89%E8%AF%BA%E5%A1%94,如果您对于阅读汉语有障碍,请移步这里http://en.wikipedia.org/wiki/Tower_of_Hanoi,我大概把问题描述摘录如下

河内塔是根据一个传说形成的一个问题:

有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:

1.   每次只能移动一个圆盘;

2.   盘不能叠在盘上面。

提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。

 

那么GG突然好奇,如果要求盘子只能从上一个杆移动到下一个杆(即只能A->B, B->C, C->A),则最少移动次数是多少?

 

Input

 

一个数N,表示圆盘的个数(1 <= N <= 20)

 

Output

只有一行表示最少的移动次数(数据保证这个数在64位有符号整数范围)

 

Sample Input

Sample Input
0

Sample Input 2
1

Sample Input 3
3

Sample Output

Sample Output
0

Sample Output 2
2

Sample Output 3
21

Source

Author

buaagg
 
 
#include<stdio.h>

int main(void)
{
    int n=0,i=0,a[28]={0,2,7,21};
    scanf("%d",&n);
    for(i=2;i+1<n;i++)//Here is My 1edit code
        a[i+2]=2*(a[i+1]+a[i])+3;
    printf("%d",a[n]);
    return 0;
}

 

So Hard

pid=49275

请将有限小数化为最简分数。
 

Input

一个整数n 表示需要转化的小数个数; 接下来n行,每行有一个有限小数。(保证小数位数不超过9位)
 

Output

输出有n行,每行为小数对应的最简分数
 

Sample Input

2
0.5
0.4

Sample Output

1/2
2/5

Hint

注意精度问题,数据保证不会有类似1.0的小数。
 

Source

 

#include<stdio.h>

int main(void)
{
    int n=0,a=0,b=1;
    char s[88]="",*p=s,*pTmp=NULL;
    scanf("%d%*c",&n);
    while(n--)
    {
        gets(s);
        for(a=0,b=1,p=s,pTmp=NULL;*p;p++)
        {
            if(pTmp)
                b*=10;
            if(*p==.)
                pTmp=p;
            else
                a=a*10+*p-0;
        }
        while(!((a|b)&1))
            a>>=1,b>>=1;
        while(!(a%5||b%5))
            a/=5,b/=5;
        printf("%d/%d
",a,b);
    }
    return 0;
}

 

 

位操作

 pid=4141

假设你工作在一个32位的机器上,你需要将某一个外设寄存器的第X位设置成0(最低位为第0位,最高位为第31位),将第Y位开始的连续三位设置成110(从高位到低位的顺序),而其他位保持不变。对给定的寄存器值R,及X,Y,编程计算更改后的寄存器值R。

 

Input

仅一行,包括R,X,Y,以逗号","分隔,R为16进制表示的32位整数,X,Y在0-31之间且Y>=3,(Y-X)的绝对值>=3,保证两次置位不会重合

 

Output

更改后的寄存器值R(16进制输出)

 

Sample Input

12345678,0,3

Sample Output

1234567c

Source

 

#include<stdio.h>

int main(void)
{
    unsigned r=0,x=0,y=0,tmp=1;
    scanf("%x%*c%d%*c%d",&r,&x,&y);
    tmp<<=x;
    r&=~tmp;
    tmp=1;
    tmp<<=y-2;
    r&=~tmp;
    tmp=3;
    tmp<<=y-1;
    r|=tmp;
    printf("%x",r);
    return 0;
}

 

实现堆结构

pid=51741

定义一个数组,初始化为空。在数组上执行两种操作:

1、增添1个元素,把1个新的元素放入数组。

2、输出并删除数组中最小的数。

使用堆结构实现上述功能的高效算法。

 

Input

第一行输入一个整数t,代表测试数据的组数。
对于每组测试数据,第一行输入一个整数n,代表操作的次数。
每次操作首先输入一个整数type。
当type=1,增添操作,接着输入一个整数u,代表要插入的元素。
当type=2,输出删除操作,输出并删除数组中最小的元素。
1<=n<=100000。

 

Output

每次删除操作输出被删除的数字

 

Sample Input

2
5
1 1
1 2
1 3
2
2
4
1 5
1 1
1 7
2

Sample Output

1
2
1

Hint

 
每组测试数据的复杂度为O(nlgn)的算法才能通过本次,否则会返回TLE(超时)
需要使用最小堆结构来实现本题的算法
 

Source

 

#include<stdio.h>
#define N 100008

int main(void)
{
    int t=0,n=0,type=1,u=0,i=0,top=1,heap[N]={0};
    scanf("%d",&t);
    while(t--)
    {
        top=1;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d",&type);
            if(type==1)
            {
                scanf("%d",&u);
                for(i=top;i>1&&u<heap[i/2];i/=2)
                    heap[i]=heap[i/2];
                heap[i]=u;
                top++;
            }
            else
            {
                printf("%d
",heap[1]);
                top--;
                for(i=1;;i=2*i+u)
                {
                    if(2*i+1<top)
                    {
                        u=heap[2*i]>heap[2*i+1];
                        if(heap[top]<=heap[2*i+u])
                            break;
                        else
                            heap[i]=heap[2*i+u];
                    }
                    else if(2*i<top)
                    {
                        if(heap[top]>heap[2*i])
                        {
                            heap[i]=heap[2*i];
                            i*=2;
                        }
                        break;
                    }
                    else
                        break;
                }
                heap[i]=heap[top];
            }
        }
    }
    return 0;
}

 

 

Square

pid=44282
 

三三画三角形画烦了,就画正方形,三三在想用N个正方形最多可以把平面分成几个区域?

 

Input

本题有多组测试数据,每组测试数据只包含一个正整数N(0<=N<=100 000 000)。

 

Output

对于每组测试数据,请输出题目中要求的结果,每组数据输出一个换行。

 

Sample Input

1

2

Sample Output

2

10

Source

Author

彭文文
 
 
#include<stdio.h>

int main(void)
{
    long long n=0;
    while(~scanf("%lld",&n))
        printf("%lld
",n?2+4*n*(n-1):1);
    return 0;
}

 

 

以上是关于Recall2019BNUOJ的主要内容,如果未能解决你的问题,请参考以下文章

Precision、Recall 和 F1 可以是相同的值吗?

BNUOJ 27935 我爱背单词(FFT)

BNUOJ 34982 Beautiful Garden

字符串BNUOJ 52781 Book Borders

BNUOJ19500 Matrix Decompressing

C1. 组队活动 Small(BNUOJ)