Recall2019BNUOJ
2019年本人在北京师范大学OJ系统上做了一些题目,现在回忆出来(代码不需要回忆,有记录,目前共8题)。
Primary Arithmetic
pid=1006
Input
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; }
最少比较次数
所以,我们常常只需要一部分比较结果,就能完成排序操作。
现在有n个整数,请问如果采用最佳的比较策略,至少需要多少次比较操作才能保证完成排序呢?
Input
如果n = 0则表示输入结束。
Output
如果n = 0则表示输入结束。
Sample Input
3 0
Sample Output
3
Hint
Source
Author
#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\n",key[n-1]); } return 0; }
转义字符
pid=1041
printf是C语言中最常用的输出函数。为了输出一些特殊字符,printf中定义了一些转义字符,但是如果想要输出这些转义字符,又需要将这些转义字符转义(囧RZ,好晕)。如果我们想输出下面这个字符串:
\"ab%d
我们不能使用
printf("\"ab%d");
输出上面的字符串,而应该改写为
printf("\\\"ab%%d");
根据经验,我们发现在我们使用的字符串中有下面几种字符需要被改写:
- \需要被改写为\\
- "需要被改写为\"
- %需要被改写为%%
给出串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='\0'; puts(res); } return 0; }
Hanoi
汉诺塔问题基本上是学习递归必举的例子,如果您对于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. 每次只能移动一个圆盘;
提示:可将圆盘临时置于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
#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
Output
Sample Input
2 0.5 0.4
Sample Output
1/2 2/5
Hint
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\n",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\n",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
三三画三角形画烦了,就画正方形,三三在想用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",n?2+4*n*(n-1):1); return 0; }
posted on 2020-05-24 20:12 Leisureeen 阅读(441) 评论(0) 编辑 收藏 举报