• Home
  • About
    • shawvey photo

      shawvey

      在写bug比赛中荣获第一名🐛

    • Learn More
    • Email
    • Twitter
    • Instagram
    • Github
  • Posts
    • All Posts
    • All Tags
  • Notes

CODE[VS]-silver

12 Mar 2018

Reading time ~25 minutes

本文目录🧾

  • 1075 明明的随机数
  • 1076 排序
  • 1083 Cantor表
  • 1160 蛇形矩阵
  • 1012 最大公约数和最小公倍数问题
  • 1212 最大公约数
  • 1430 素数判定
  • 1474 十进制转m进制
  • 1475 m进制转十进制
  • 1011 数的计算
  • 1978 Fibonacci数列 3
  • 1501 二叉树最大宽度和高度
  • 1842 递归第一次
  • 3038 3n+1问题
  • 3143 二叉树的序遍历
  • 3145 汉诺塔游戏

正文部分📝

终于做完silver了,准备做Gold了。这次不仅要打蓝桥杯还有天梯赛,啊~感觉对二叉树很不熟,以后晚上回去要看之前买的数据结构书才行了,不然难题肯定做不出来。

1075 明明的随机数

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

#include <stdio.h>  
int main( )  
{  
   int i,a[100],b[100],n,temp,j,r,pos;    
   scanf("%d",&n);
   for( i = 0; i < n;i++ ){
	scanf("%d",&a[i]);
   }
   r=0;
   for(i=0;i<n;i++){
	if(i==0){
		b[r]=a[i];
		r++;
	}
	else{
		pos=0;
		for(j=0;j<r;j++){
			if(a[i]==b[j]){
				pos++;
			}
		}
		if(pos==0){
			b[r]=a[i];
			r++;
		}
	}
	
   }
   for(j=r-1;j>=0;j--){
	for(i=0;i<j;i++){
		if(b[i]>b[i+1]){
			temp=b[i];
			b[i]=b[i+1];
			b[i+1]=temp;
		}
	}
}
    printf("%d\n",r);
	for( i = 0; i < r;i++ ){
	   printf("%d ",b[i]); 
   }
   return 0;
}  

1076 排序

给出n和n个整数,希望你从小到大给他们排序。
这里使用C++里的函数会起到事半功倍的作用!

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
 int i,a[100000],n;    
 cin>>n;
 for( i = 0; i < n;i++ )
	cin>>a[i];
 sort(a,a+n);
 for(i=0;i<n;i++)
 cout<<a[i]<<' ';
 return 0;
}

1083 Cantor表

现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … 3/1 3/2 3/3 … 4/1 4/2 … 5/1 … … 我们以Z字形给上表的每一项编号。第一项是1/1,然后是1/2,2/1,3/1,2/2,…

#include<stdio.h>
#include"math.h"
int main(){
	double n;
	int value,front,deal;
	scanf("%lf",&n);
	value=sqrt(2*(n+1));
	front=n-((1+value-1)*(value-1))/2;
	if(value%2==0){
		printf("%d/%d",front,value+1-front);		
	}
	else{
		printf("%d/%d",value+1-front,front);
	}
	return 0;
}   

1160 蛇形矩阵

小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和.

#include<stdio.h>
int main(){
	int n,a[100][100],square,i,j,djx=0;
	scanf("%d",&n);
	square=n*n;
	for(i=0;i<n/2;i++){
		for(j=n-1-i;j>=1+i;j--){
			a[n-1-i][j]=square;
			square--;
		}
		for(j=n-1-i;j>=1+i;j--){
			a[j][i]=square;
			square--;
		}
		for(j=i;j<=n-2-i;j++){
			a[i][j]=square;
			square--;
		}
		for(j=i;j<=n-2-i;j++){
			a[j][n-1-i]=square;
			square--;
		}
	}
	a[n/2][n/2]=square;
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			printf("%d ",a[i][j]);
			if(i==j){
				djx+=a[i][j];
			}
			if(i+j==n-1){
				djx+=a[i][j];
			}
		}
		printf("\n");
	}
	printf("%d",djx-1);
	return 0;
} 

1012 最大公约数和最小公倍数问题

输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数,条件: 1.P,Q是正整数
2.要求P,Q以x0为最大公约数,以y0为最小公倍数.
试求:满足条件的所有可能的两个正整数的个数.

#include<stdio.h>
#include <stdbool.h>
bool isok(int a,int b){
	int min,i,q=0;
	min=a<b?a:b;
	for(i=2;i<=min;i++){
		if(a%i==0&&b%i==0){
			q=1;
		}
	}
	if(q==0){
		return true;
	} 
	else{
		return false;
	}
}
int main(){
	int x0,y0,value,value2,i,j,temp,count;
	scanf("%d %d",&x0,&y0);
	if(y0%x0==0){
		value=y0/x0;
		count=2;
		for(i=2;i<=value/2;i++){
		if(value%i==0){
			value2=value/i;
			if(isok(i,value2)){
				count+=1; 
			}
		}
	}
	printf("%d",count);
	}
	else{
		printf("%d",0);
	}

	return 0;
}

1212 最大公约数

求两个数A和B的最大公约数。 1<=A,B<=2^31-1

#include<stdio.h>
long long gcd(long long a,long long b){
	long long i,min,gys;
	min=a<b?a:b;
	for(i=1;i<=a;i++){
		if(a%i==0&&b%i==0){
			gys=i;
		}
	}
	return gys;
}
int main(){
	long long a,b;
	scanf("%lld %lld",&a,&b);
	printf("%lld",gcd(a,b));
	return 0;
} 

1430 素数判定

质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数。
素数在数论中有着很重要的地位。比1大但不是素数的数称为合数。1和0既非素数也非合数。质数是与合数相对立的两个概念,二者构成了数论当中最基础的定义之一。基于质数定义的基础之上而建立的问题有很多世界级的难题,如哥德巴赫猜想等。算术基本定理证明每个大于1的正整数都可以写成素数的乘积,并且这种乘积的形式是唯一的。这个定理的重要一点是,将1排斥在素数集合以外。如果1被认为是素数,那么这些严格的阐述就不得不加上一些限制条件。
概念:
只有1和它本身两个约数的自然数,叫质数(Prime Number)。(如:由2÷1=2,2÷2=1,可知2的约数只有1和它本身2这两个约数,所以2就是质数。与之相对立的是合数:“除了1和它本身两个约数外,还有其它约数的数,叫合数。”如:4÷1=4,4÷2=2,4÷4=1,很显然,4的约数除了1和它本身4这两个约数以外,还有约数2,所以4是合数。)
100以内的质数有2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,在100内共有25个质数。
注:(1)1既不是质数也不是合数。因为它的约数有且只有1这一个约数。(2)2和3是所有素数中唯一两个连着的数。

#include<stdio.h>
#include <stdbool.h>
bool isprime(int n){
	int flag=0,i;
	if(n==1&&n==2){
		return true;
	}
	else{
	for(i=2;i<n/2;i++){
		if(n%i==0){
			flag=1;
		}
	}
	if(flag==0){
		return true;
	}
	else{
		return false;
	}
	}
}
int main(){
	int n;
	scanf("%d",&n);
	if(isprime(n)){
		printf("\\t");
	}
	else{
		printf("\\n");
	}
	return 0;
}

1474 十进制转m进制

将十进制数n转换成m进制数 m<=16 n<=100

#include<stdio.h>
int main(){
	int n,m,a[100],i,num=0;
	scanf("%d %d",&n,&m);
	do{
		a[num]=n%m;
		n=n/m;
		num++;
	}while(n!=0);
	for(i=num-1;i>=0;i--){
		if(a[i]<=9){
		printf("%d",a[i]);
		}
		else{
			printf("%c",65+a[i]-10);
		}
	
	}
	return 0;
}

1475 m进制转十进制

将m进制数n转化成一个十进制数 m<=16
题目保证转换后的十进制数<=100

#include<stdio.h>
#include<math.h>
#include <string.h>
int main(){
	int m,count=0,length,value;
	long num=0;
	char a[10000];
	scanf("%s %d",a,&m);
	length=strlen(a)-1;
	while(length>=0){
		if(a[length]=='A'){
			num+=10*pow(m,count);
		}
		else if(a[length]=='B'){
			num+=11*pow(m,count);
		}
		else if(a[length]=='C'){
			num+=12*pow(m,count);
		}
		else if(a[length]=='D'){
			num+=13*pow(m,count);
		}
		else if(a[length]=='E'){
			num+=14*pow(m,count);
		}
		else if(a[length]=='F'){
			num+=15*pow(m,count);
		}
		else{
			num+=(a[length]-48)*pow(m,count);
		}
		count++;
		length--;
	};

	printf("%d",num);
	return 0;
}

1011 数的计算

我们要求找出具有下列性质数的个数(包含输入的自然数n):
先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理:
1.不作任何处理;
2.在它的左边加上一个自然数,但该自然数不能超过原数的一半;
3.加上数后,继续按此规则进行处理,直到不能再加自然数为止.

#include<stdio.h>

int f(int n){                    
  int s=1,i;                         
  for(i=1; i<=n/2; i++)       
    s+=f(i);
  return s;
}

int main(){
  int n;
  scanf("%d",&n);
  printf("%d",f(n));
  return 0;
}

1978 Fibonacci数列 3

斐波纳契数列是这样的数列: f1 = 1
f2 = 1
f3 = 2
f4 = 3
….
fn = fn-1 + fn-2
输入一个整数n
求fn

#include<stdio.h>
int fibonacci(int n){
	if(n==1||n==2){
		return 1; 
	}
	else{
		return fibonacci(n-1)+fibonacci(n-2);
	}
}
int main(){
	int n;
	scanf("%d",&n);
	printf("%d",fibonacci(n)); 
	return 0;
}

1501 二叉树最大宽度和高度

给出一个二叉树,输出它的最大宽度和高度。

#include <stdio.h>  
#include <string.h>  
  
int a[1000][2],s[1000];  
int i,n,x,y;   
  
void dfs(int i,int k)  
{  
    s[k]=s[k]+1;  
    if(k>x)  x=k;  
    if(a[i][1]!=0){
    	dfs(a[i][1],k+1);
    }
    if(a[i][2]!=0)  dfs(a[i][2],k+1);  
}  
  
int main()  
{  
    scanf("%d",&n);  
    memset(a,0,sizeof(a));  
    memset(s,0,sizeof(s));  
    for(i=1;i<=n;i++)  
        scanf("%d%d",&a[i][1],&a[i][2]);  
    x=0;  
    dfs(1,1);  
    y=0;  
    for(i=1;i<1000;i++)  
        if(s[i]>y)   y=s[i];  
    printf("%d %d",y,x);  
    return 0;  
}  

1842 递归第一次

同学们在做题时常遇到这种函数
f(x)=5 (x>=0)
f(x)=f(x+1)+f(x+2)+1 (x<0)
下面就以这个函数为题做一个递归程序吧

#include<stdio.h>
int f(int n){
	if(n>=0){
		return 5;
	}
	else{
		return f(n+1)+f(n+2)+1;
	}
}
int main(){
	int n;
	scanf("%d",&n);
	printf("%d",f(n));
	return 0;
} 

3038 3n+1问题

3n+1问题是一个简单有趣而又没有解决的数学问题。这个问题是由L. Collatz在1937年提出的。克拉兹问题(Collatz problem)也被叫做hailstone问题、3n+1问题、Hasse算法问题、Kakutani算法问题、Thwaites猜想或者Ulam问题。
问题如下:
(1)输入一个正整数n;
(2)如果n=1则结束;
(3)如果n是奇数,则n变为3n+1,否则n变为n/2;
(4)转入第(2)步。
克拉兹问题的特殊之处在于:尽管很容易将这个问题讲清楚,但直到今天仍不能保证这个问题的算法对所有可能的输入都有效——即至今没有人证明对所有的正整数该过程都终止。

#include<stdio.h>
int main(){
	int a[100],T,i,b[100];
	scanf("%d",&T);
	for(i=0;i<T;i++){
		scanf("%d",&a[i]);
	}
	for(i=0;i<T;i++){
		b[i]=0;
		while(a[i]!=1){
			if(a[i]%2==0){
				a[i]=a[i]/2;
			}
			else{
				a[i]=3*a[i]+1;
			}
			b[i]++;
		}
	}
	for(i=0;i<T;i++){
		printf("%d\n",b[i]);
	}
	return 0;
}

3143 二叉树的序遍历

求一棵二叉树的前序遍历,中序遍历和后序遍历。

#include<stdio.h>
#include<string.h>
int a[20][2];
void center(int k){
	printf("%d ",k);
	if(a[k][0]){
		center(a[k][0]);
	}
	if(a[k][1]){
		center(a[k][1]);
	}
}
void left(int k){
	if(a[k][0]){
		left(a[k][0]);
	}
	printf("%d ",k);
	if(a[k][1]){
		left(a[k][1]);
	}
}
void right(int k){
	if(a[k][0]){
		right(a[k][0]);
	}
	if(a[k][1]){
		right(a[k][1]);
	}
	printf("%d ",k);
}
int main(){
	int n,i;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d %d",&a[i][0],&a[i][1]);
	}
	center(1);
	printf("\n");
	left(1);
	printf("\n");
	right(1);
	printf("\n");
	return 0;
} 

3145 汉诺塔游戏

汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题。在A,B,C三根柱子上,有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我A上(如图所示),你的目标是在最少的合法移动步数内将所有盘子从A塔移动到C塔。
游戏中的每一步规则如下:
1.每一步只允许移动一个盘子(从一根柱子最上方到另一个柱子的最上方)
2.移动的过程中,你必须保证大的盘子不能在小的盘子上方(小的可以放在大的上面,最大盘子下面不能有任何其他大小的盘子)
如对于n=3的情况,一个合法的移动序列式:
1 from A to C
2 from A to B
1 from C to B
3 from A to C
1 from B to A
2 from B to C
1 from A to C
给出一个数n,求出最少步数的移动序列。

#include<stdio.h>
#include<math.h>
void hanoi(int n,char a,char b,char c){
	if(n==1){
		printf("%d from %c to %c\n",n,a,c);
        return;
	}
	else{
		hanoi(n-1,a,c,b);
		printf("%d from %c to %c\n",n,a,c);
		hanoi(n-1,b,a,c);
	}
}
int main(){
	int n;
	int times;
	scanf("%d",&n);
	times=pow(2,n)-1;
	printf("%d\n",times);
	hanoi(n,'A','B','C');
	return 0;
} 


C/C++ Share Tweet +1