蓝桥杯真题练习

蓝桥杯真题练习


前言

为准备考研复试上机考试,练习蓝桥杯真题,记录每一题的思路、问题及代码


一、2023年软件类省赛C/C++大学A组

1.平方差

题目链接

平方差n=m^2 - k^2=(m-k)(m+k),令m-k=x,m+k=y,
则可得m=(x+y)/2,n=(x-y)/2。若m,n均为整数,则x+y,x-y均为偶数,则x和y同奇偶(奇+奇=偶,奇-奇=偶,偶+偶=偶,偶-偶=偶)。
进一步:n=xy
1)x和y同偶:x和y均为2的倍数,则n为4的倍数
2)x和y同奇:n=xy仍为奇数
综上:n为4的倍数,或奇数

#include<stdio.h>
int main()
{
    int L,R;
    scanf("%d %d", &L, &R);
    int count=0;//计数
    for(int i=L;i<=R;i++){//判断是不是平方差:是4的倍数,或是奇数
        if(i%4==0 || i%2!=0)
            count++;
    }
    printf("%d\n",count);
    return 0;
}

2.更小的数

题目链接

自己的思路:遍历字符串的每一个子串,将该子串逆置,将字符串转为数,比较逆置后的数和原来的数的大小,代码如下
结果输出为0,错误

#include<stdio.h>
#include<string.h>
int toNum(char *s){//字符串转整数
    int result=0;
    for(int i=0;s[i]!='\0';i++){
        result=result*10;
        result+=i-'0';
    }
    return result;
}
void reverse(char *s,int a,int b){//将下标a到b的子串翻转
    
    char temp;
    
    while(a<b){
        temp=s[a];
        s[a]=s[b];
        s[b]=temp;
        a++;b--;
    }
}
int main()
{
	printf("**************************\n");
	printf("dotcpp.com\n");
	printf("**************************\n");
	char s[100];
	char snew[100];
	scanf("%s",s);
	
	//字符串转整数
	int x=toNum(s);
	int y,count=0;
	int len=strlen(s);
	for(int i=0;i<=len-2;i++){
	    for(int j=i+1;j<=len-1;j++){
	        strcpy(snew,s);
	        reverse(snew,i,j);
	        y=toNum(snew);
	        if(y<x)
	            count++;
	    }
	}
	printf("%d\n",count);
	return 0;
}

看答案的思路:
遍历每个子串,比较子串第一个字符和最后一个字符的大小。如果第一个字符大于最后一个字符,则该子串逆置之后的数一定小于原数;如果第一个字符等于最后一个字符,则继续看第二个字符和倒数第二个字符的大小,如果第二个字符大于倒数第二个字符,则该子串逆置之后的数一定小于原数(找到一个就可以跳出这个子串的循环了,继续找下一个子串);如果第二个字符小于倒数第二个字符,则该子串逆置之后的数一定大于原数,继续找下一个子串;如果第二个字符等于倒数第二个字符,则继续向内找。
代码如下:

#include<stdio.h>
#include<string.h>
int main()
{//后面的数比前面的小则交换后的数小
	char s[5000];
	scanf("%s",s);
	int count=0;
	int len=strlen(s);
	int a,b;
	for(int i=0;i<=len-2;i++){
	    for(int j=i+1;j<=len-1;j++){//遍历每个子串
	        if(s[i]>s[j])
	            count++;
	        else if(s[i]==s[j]){
	           a=i+1;
	           b=j-1;
	           while(a<b){
	               if(s[a]>s[b]){
	                   count++;
	                   break;
	               }
	               else if(s[a]<s[b])//若后面的数大于前面的数则pass
	                   break;
	               a++;
	               b--;
	           }
	       }
	    }
	}
	printf("%d\n",count);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值