蓝桥杯——基础训练(二)
特殊的数字(循环+判断+数位)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 153是一个非常特殊的数,它等于它的每位数字的立方和,即153=111+555+333。编程求所有满足这种条件的三位十进制数。
输出格式
- 按从小到大的顺序输出满足条件的三位十进制数,每个数占一行。
AC
#include <stdio.h>
int main(){
	int i,g,s,b;
	for(i=100;i<1000;i++){
		g=i%10%10;	//个位 
		s=i/10%10;	//十位
		b=i/100;	//百位
		if(i==g*g*g+s*s*s+b*b*b)	printf("%d\n",i); 
	}
	return 0;
} 
回文数(循环+判断+回文数)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数。
输出格式
- 按从小到大的顺序输出满足条件的四位十进制数。
思考
- 将每个数的位数两层循环打印出来。
AC
#include <stdio.h>
int main(){
	int i,j;
	for(i=1;i<=9;i++){
		for(j=1;j<=9;j++){
			printf("%d%d%d%d\n",i,j,j,i);
		}
	}
	return 0;
} 
特殊回文数(回文数+循环+条件语句)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 123321是一个非常特殊的数,它从左边读和从右边读是一样的。
- 输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。
输入格式
- 输入一行,包含一个正整数n。
输出格式
- 按从小到大的顺序输出满足条件的整数,每个整数占一行。
样例输入
- 52
样例输出
899998
989989
998899
数据规模和约定
- 1<=n<=54。
AC
#include <stdio.h>
int main(){
	int i,j,k,n;
	scanf("%d",&n);
	for(i=1;i<=9;i++)	//所有这样的五位十进制数
		for(j=0;j<=9;j++)
			for(k=0;k<=9;k++)
				if(n==(i+j)*2+k)
					printf("%d%d%d%d%d\n",i,j,k,j,i);
	
	for(i=1;i<=9;i++)	//所有这样的六位十进制数
		for(j=0;j<=9;j++)
			for(k=0;k<=9;k++)
				if(n==(i+j+k)*2)
					printf("%d%d%d%d%d%d\n",i,j,k,k,j,i);
	return 0;
}
十进制转十六进制(循环+整除+求余+判断)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。
- 给出一个非负整数,将它表示成十六进制的形式。
输入格式
- 输入包含一个非负整数a,表示要转换的数。0<=a<=2147483647
输出格式
- 输出这个整数的16进制表示
样例输入
- 30
样例输出
- 1E
思考
- 十进制转化为十六进制计算方式,简单说就是整数除以16取余,直到商为0为止,然后从最后一个余数读到第一个。
- 注意0的存在!!!
AC
#include <stdio.h>
int main(){
	int n,i,str[100],num=0;
	scanf("%d",&n); 
	if(n==0)	printf("%d",n);	//如果为0,16进制仍为 0  
	while(n!=0){	//计算每一位的余数,存入数组 
		int fs=n;
		n=n/16;
		str[num++]=fs%16;
	}
	for(i=num-1;i>=0;i--){	//逆序输出 
		if(str[i]>9 && str[i]<16)
			printf("%c",str[i]-10+'A');
		else
			printf("%d",str[i]);
	}
	printf("\n");
	return 0;
} 
十六进制转十进制(进制转换+字符处理+判断)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。
- 注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。
样例输入
- FFFF
样例输出
- 65535
思考
- 十六进制转换成十进制的具体算法是:
- 首先明白16进制数(从右到左数是第0位,第1位,第2位……)的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方,依次这样排列下去。
- 明白ABCDEF表示的二进制数字分别是10,11,12,13,14,15。
- 十六进制转换成十进制的公式是:要从右到左用二进制的每个数去乘以16的相应次方,然后这些数字相加就是了。
例1:2AF5换算成10进制:
第0位: 5 * 16^0 = 5
第1位: F * 16^1 =15*16^1= 240
第2位: A * 16^2= 10* 16^2=2560
第3位: 2 * 16^3 = 8192
结果就是:5 * 16^0 + 15 * 16^1 + 10 * 16^2 + 2 * 16^3 = 10997
例2:CE换算成10进制:
第0位:E*16^0=14*16^0=14
第1位:C*16^1=12*16^1=192
结果就是:14*16^0+12*16^1=206
- 错了三次,只要还是细节问题,在-‘0’时,变成了+。
- 调用了两个函数,绝对值函数pow(),求字符串长度的函数strlen(),如果不用函数,也可以,但代码会有点长。
- 本题也有陷阱,也是出在数据范围上,不超过8位的十六进制数,所以计算总和的sum应该声明为long型,而不是int型,否则会出错。
AC
#include <stdio.h>
#include <math.h>	//调用pow()函数 
#include <string.h>	//调用strlen()函数 
int main(){
	long long y=0;
	int i;
	char x[8];
	scanf("%s",x);
	for(i=0;i<strlen(x);i++){
		if(x[i]<'0'+10){	//单个字符小于10即当字符为数字时
			y += (x[i]-'0')*pow(16,strlen(x)-1-i);
		}else{	//当字符为字母时 
			y += (x[i]-'A'+10)*pow(16,strlen(x)-1-i);
		}
	}
	printf("%lld\n",y);
	return 0;
}
十六进制转八进制(进制转换+字符+循环)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
- 输入的第一行为一个正整数n (1<=n<=10)。
- 接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
- 输出n行,每行为输入对应的八进制正整数。
【注意】
- 输入的十六进制数不会有前导0,比如012A。
- 输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
- 先将十六进制数转换成某进制数,再由某进制数转换成八进制。
思考
- 100000位的十六进制数,这么大的数不好直接处理,先将十六进制数转换成二进制数,再由二进制数转换成八进制。
- 使用c++中的string库解决此问题
- 注意前导0的输出
测试数据 39
十六进制 0011 1001
不够三的倍数 +0(使用string中的t=”00”+t非常方便)
加0后 000 111 001
输出八进制 0 7 1此时的前导0 去电
结果 71
AC
#include<iostream>
#include<string>
using namespace std;
int main(){
	int n,i,k,len,flag,sum;
	string s,t;
	cin>>n;
	for (k=0;k<n;k++) {
		cin>>s;
		t="";//字符串的初始化 
		for (i=0;i<s.length();i++) {
			switch(s[i]) {
				case '0':t+="0000";break;
				case '1':t+="0001";break;
				case '2':t+="0010";break;
				case '3':t+="0011";break;
				case '4':t+="0100";break;
				case '5':t+="0101";break;
				case '6':t+="0110";break;
				case '7':t+="0111";break;
				case '8':t+="1000";break;
				case '9':t+="1001";break;
				case 'A':t+="1010";break;
				case 'B':t+="1011";break;
				case 'C':t+="1100";break;
				case 'D':t+="1101";break;
				case 'E':t+="1110";break;
				case 'F':t+="1111";break;
			}
		}
		len=t.length();
		if(len%3==1){//16进制转换成2进制后填0 
			t="00"+t;
		}else if(len%3==2) {
			t="0"+t;
		}
		flag=0;
		for (i=3;i<=t.length();i+=3) {
			sum=(t[i-3]-'0')*4+(t[i-2]-'0')*2+t[i-1]-'0';
			if(sum)//控制第一次的前导不为0 
				flag=1;
			if(flag)
			    cout<<sum;
		}
		cout<<endl;
	}
	return 0;
}
- 直接使用java自带的方法去转就行了,不过值得注意的是,因为是先从16进制转为10进制,再从10进制转为8进制,所以要用BigInteger,防止爆0
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine(); // 换行
        for (int i = 0; i < n; i++) {
        // 从16转10再转8
            System.out.println(new BigInteger(sc.nextLine(),16).toString(8));
        }
    }
}
数列排序(数组+排序)
资源限制
- 时间限制:1.0s 内存限制:512.0MB
问题描述
- 给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200
输入格式
- 第一行为一个整数n。
- 第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000。
输出格式
- 输出一行,按从小到大的顺序输出排序后的数列。
样例输入
5
8 3 6 4 9
样例输出
3 4 6 8 9
思考
- 自定义一个qsort()函数,因为C中没有C++中的sort()函数。
AC
#include <stdio.h>
int cmp(const void *a,const void *b){
	return *(int*)a-*(int*)b;
}
int main(){
	int n,i,str[10010];
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&str[i]);
	}
	qsort(str,n,sizeof(str[0]),cmp);
	for(i=0;i<n;i++){
		printf("%d ",str[i]);
	}
	return 0;
}
因为不是VIP,所以官网的题库的基础训练部分就只能写到这。虽然其它网站也有原题,但官网的OJ更合适。
    欢迎查阅
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号