蓝桥杯基础练习超全习题题解VIP版——BASIC-14~19(时间转换、字符串对比、分解质因数、矩阵乘法、矩形面积交、完美的代价)

每日刷题(三十)

BASIC-14、时间转换

在这里插入图片描述
在这里插入图片描述
这题非常简单,这里就不做过多赘述了,详细C代码如下

#include<stdio.h>

int main()
{
	int n;
	scanf("%d", &n);
	printf("%d:%d:%d\n", n / 3600, n % 3600 / 60, n % 3600 % 60);
	return 0;
}

部分示例结果展示如下
在这里插入图片描述

在这里插入图片描述

BASIC-15、字符串对比

在这里插入图片描述
在这里插入图片描述
这个题其实给人的思路也很清晰,分四类讨论,第一个划分条件是两个字符串的长度是否相等,第二个划分条件是字符串是否相等,第三个划分条件是不考虑大小写字符串是否相等。详细C代码如下:

#include<stdio.h>
#include<string.h>
#include<math.h>

int f(char s1[], char s2[])
{
	int i, num = 0;
	for(i = 0; s1[i] != '\0'; i++)
	{
		if(abs(s1[i] - s2[i]) == 32)
			num++;
		else if(s1[i] == s2[i])
			num++;
	}
	if(num == i)
		return 1;
	else
		return 0;	
}

int main()
{
	char s1[10], s2[10];
	scanf("%s", s1);
	scanf("%s", s2);
	int c1, c2;
	c1 = strlen(s1);
	c2 = strlen(s2);
	if(c1 != c2)
		printf("1\n");
	else
	{
		if(strcmp(s1, s2) == 0)
			printf("2\n");	
		else if(f(s1, s2))
			printf("3\n");
		else
			printf("4\n");
	}
	return 0;
}

部分示例运行结果如下:
在这里插入图片描述
在这里插入图片描述

BASIC-16、分解质因数

在这里插入图片描述
在这里插入图片描述
对于这道题的题意,有一部分人可能没读懂,质因数就是这个数既是质数,同时又是组成k的乘数之一。根据样例输入可以发现一个规律,奇数的质因数绝对都是奇数,而偶数的质因数一定有2,那么就要分两种情况考虑,一种是目标数是奇数,一种是目标数是偶数,而且对于大多数数据而言,他们都有很多质因数,所以就要用变量k来装i的值,进行运算。这里还要考虑输出格式的问题,如果目标数含有两个及其以上的质因数,那么就要考虑符号的输出格式,这里我们用cnt记载有多少质因数。当只有一个时,就输出数字无须附上*,所以在奇偶条件内还要包括一层if语句,详细C代码如下:

#include<stdio.h>

int main()
{
	int n, m;
	scanf("%d %d", &n, &m);
	int i;
	int k;
	int cnt;
	for(i = n; i <= m; i++)
	{
		cnt = 0;				//质因数个数 
		printf("%d=",i);
		k = i;
		while(k != 1)
		{
			if(k % 2 == 0)		//本为偶数
			{
				
				if(cnt >= 1)
					printf("*2");
				else
					printf("2");
				k /= 2;
				cnt++; 
			} 
			else				//本为奇数 
			{
				int j;
				for(j = 3; j < m; j += 2)
				{
					if(k % j == 0)
					{
						
						if(cnt >= 1)
							printf("*%d",j);
						else
							printf("%d",j);
						k /= j;
						cnt++;
						break;
					}
				}
			}
		}
		printf("\n");
	}
}

部分示例运行结果如下:
在这里插入图片描述

BASIC-17、矩阵乘法

在这里插入图片描述
在这里插入图片描述
这个题还是很值得思考的。这里也有很多坑。
(1)要考虑幂数,如果幂为0,那么矩阵处理后就应该是单位矩阵,如果幂为1,则矩阵就是为输入的矩阵本身,当然,需要注意输出格式。
(2)要考虑如何处理已经乘完的矩阵同时又不影响乘法过程,我这里设了三个数组,a[N][N]用来继承原始数组数据,b[N][N]开始初始化时跟a数组的值一样,但之后b数组就来承接依次幂运算后的结果,c[N][N]数组用来继承每一轮矩阵乘法后的数组,等一次矩阵乘法结束后再把它的值赋给b,以便下一次矩阵运算。
(3)要考虑数组数据大小,如果数据可能超出int所能记录的范围,可以考虑全程用long long型

我这里有两款C代码,一种是普通版,一种是高阶版(用了二维指针)

普通版:

#include<stdio.h>
int N;

void f(long long a[][N], long long b[][N], long long c[][N])
{
	int i, j, t, k;
	long sum;
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{
			sum = 0;
			for(t = 0; t < N; t++)
			{
				sum += a[i][t] * b[t][j];
			}
			c[i][j] = sum;
		}
	}
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{
			b[i][j] = c[i][j];
		}
	}
}

int main()
{
	int M;
	scanf("%lld %lld", &N, &M);
	int i, j;
	long long a[N][N];
	long long b[N][N];
	long long c[N][N];
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{
			scanf("%lld", &a[i][j]);
			b[i][j] = a[i][j];
		}
	}
	int t;
	for(t = 1; t < M; t++)
	{
		f(a, b, c);
	}
	
	if(M > 1)
	{
		for(i = 0; i < N; i++)
		{
			for(j = 0; j < N; j++)
			{
				printf("%lld ",b[i][j]);
			}
			printf("\n"); 
		}	
	}
	else if(M == 1)
		{
			for(i = 0; i < N; i++)
			{
				for(j = 0; j < N; j++)
				{
					printf("%lld ", a[i][j]);
				}
				printf("\n"); 
			}
		}
	else if(M == 0)
		{
			for(i = 0; i < N; i++)
			{
				for(j = 0; j < N; j++)
				{
					if(i == j)
						a[i][j] = 1;
					else
						a[i][j] = 0;
					printf("%lld ", a[i][j]);
				}
				printf("\n");
			}
		}
	return 0;
} 

高阶版:

#include<stdio.h>
int N;

void f(int (*p)[N], int (*q)[N], int (*k)[N])
{
	int i, j, t;
	int sum;
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{
			sum = 0;
			for(t = 0; t < N; t++)
			{
				sum += *(*(p + i) + t) * (*(*(q + t) + j));
			}
			*(*(k + i) + j) = sum;
		}
	}
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{
			*(*(q + i) + j) = *(*(k + i) + j);
		}
	}
}

int main()
{
	int M;
	scanf("%d %d", &N, &M);
	int i, j;
	int a[N][N];
	int b[N][N];
	int c[N][N];
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{
			scanf("%d", &a[i][j]);
			b[i][j] = a[i][j];
		}
	}
	int t;
	int (*p)[N] = a;
	int (*q)[N] = b;
	int (*k)[N] = c;
	for(t = 1; t < M; t++)
	{
		f(p, q, k);
	}
	
	if(M > 1)
	{
		for(i = 0; i < N; i++)
		{
			for(j = 0; j < N; j++)
			{
				printf("%lld ",b[i][j]);
			}
			printf("\n"); 
		}	
	}
	else if(M == 1)
		{
			for(i = 0; i < N; i++)
			{
				for(j = 0; j < N; j++)
				{
					printf("%lld ", a[i][j]);
				}
				printf("\n"); 
			}
		}
	else if(M == 0)
		{
			for(i = 0; i < N; i++)
			{
				for(j = 0; j < N; j++)
				{
					if(i == j)
						a[i][j] = 1;
					else
						a[i][j] = 0;
					printf("%lld ", a[i][j]);
				}
				printf("\n");
			}
		}
	return 0;
} 

在这里插入图片描述
内存使用都一样大,第一个是高阶版,第二个是普通版的结果。

部分示例运行结果如下:
在这里插入图片描述
在这里插入图片描述

BASIC-18、矩形面积交*

在这里插入图片描述
在这里插入图片描述
这题很简单,注释里已经写的很清楚了,详细代码如下:

#include<stdio.h>

double max(double a, double b)
{
	return (a > b ? a : b);
}

double min(double a, double b)
{
	return (a < b ? a : b);
}


int main()
{
	double x1, y1, x2, y2, x3, y3, x4, y4;
	scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
	scanf("%lf %lf %lf %lf", &x3, &y3, &x4, &y4);
	double l1, l2, r1, r2;
	l1 = max(min(x1, x2), min(x3, x4));			//相交面积的左下角区域横坐标 
	l2 = max(min(y1, y2), min(y3, y4));			//相交面积的左下角区域纵坐标 
	r1 = min(max(x1, x2), max(x3, x4));			//相交面积的右上角区域横坐标
	r2 = min(max(y1, y2), max(y3, y4)); 		//相交面积的右上角区域纵坐标
	
	if(l1 < r1 && l2 < r2)
		printf("%.2lf\n", (r1 - l1) * (r2 - l2));
	else
		printf("0.00\n");	
	return 0;
}

部分示例结果如下:
在这里插入图片描述

BASIC-19、完美的代价

在这里插入图片描述
在这里插入图片描述
这个题很有价值,很有逻辑性。

这肯定要分情况讨论。
1、Impossible的情况:
      i)字符串长度N为偶数:如果存在一种字符的重复次数为奇数,那么肯定无法构成回文串;
      ii)字符串长度N为奇数:如果存在两种及其以上的字符的重复次数为奇数,那么也无法构成回文串
2、可构成回文串的情况:
      i)字符串长度N为偶数:则从第0到N/2 - 1遍历,排出回文串,并记录交换次数
      ii)字符串长度N为奇数:则从第0到N/2 - 1遍历,排出回文串,并记录交换次数,如果遇到无法匹配的数字,则设一些标识变量记录数字,保证后续可能遍历不受影响,最后再根据标识情况移动数字,并记录交换次数

详细代码如下:

#include<stdio.h>

int main()
{
	int N;
	scanf("%d", &N);
	char a[N];
	getchar();		//消化回车
	gets(a);
	int b[26] = {0};
	int i;
	for(i = 0; i < N; i++)
	{
		b[a[i] - 'a']++;
	} 
	
	int cnt = 0;
	for(i = 0; i < 26; i++)
	{
 		if(b[i] % 2)		
			cnt++;				//得出出现奇数次的字母的种类个数 
	}
	
	if(N % 2 == 0)				//字符数为偶数的字符串	 
	{
		if(cnt >= 1)
		{
			printf("Impossible\n");
			return 0;
		}	
		int k, t, j, num = 0;
		for(t = 0; t < N / 2; t++)		//循环遍历所有左边字符构造回文串 
		{
			k = N - 1 - t;
			j = k;
			while(a[t] != a[j])			//先找到与a[i]配对的字符 
			{
				j--;			
			}  
			char tmp;			//用来交换字符 
			while(j != k)
			{
				tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
				j++;
				num++;			//记录交换次数 
			} 
		}
//		for(i = 0; i < N; i++)
//			printf("%c", a[i]);
		printf("%d\n", num);
	} 
	if(N % 2)				//字符数为奇数的字符串 
	{
		if(cnt >= 2)
		{
			printf("Impossible\n");
			return 0;
		}
		int k, t, j, num = 0;
		int cn;
		k = N - 1;
		int flag = -1;
		for(t = 0; t < N / 2; t++)		//循环遍历所有左边字符构造回文串 
		{
		    cn = -1;
			j = k;
			while(a[t] != a[j])			//先找到与a[i]配对的字符 
			{
				j--;		
				if(j == t)
				{
					cn = t;
					break;
				}	
			}  
			
			char tmp;			//用来交换字符 
			if(cn != -1)
			{
				flag = t;
				continue;
			}
			else
			{
				while(j != k)
				{
					tmp = a[j];
					a[j] = a[j + 1];
					a[j + 1] = tmp;
					j++;
					num++;			//记录交换次数 
				} 
				k--;
			}	
				
		}
		if(flag < N / 2 && flag != -1)
		{
			int c1;
			int tmp1;
			for(c1 = flag; c1 < N / 2; c1++)
			{
				tmp1 = a[c1];
				a[c1] = a[c1 + 1];
				a[c1 + 1] = tmp1;
				num++;
			}
			
		}
//		for(i = 0; i < N; i++)
//			printf("%c", a[i]);
//		printf("\n");
		printf("%d\n", num);
		
	}
	 
	return 0;
}

部分示例运行结果如下:
在这里插入图片描述

如果喜欢我的文章,请记得三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持,下期更精彩!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值