自学c/c++遇见的编程错误及笔记

有没有大神帮忙指导一下新人,感谢!!


第一个:bool函数

蓝桥杯例题2020(p1508)


问题描述:门牌制作

 错误代码:

#include<iostream>
using namespace std;
bool check(int n){
    while(n){
        int num=n%10;
        if(num==2)
            return true;     //这里导致2020只会返回一个true
        n/=10;
    }
    return false;
}
signed main(){
    int sum=0;
    for(int i=1;i<=2020;i++){
        if(check(i))
            sum++;
    } 
    cout<<sum;
    return 0;
}

原因分析:

1.check函数中,如2020有两个数字2,但只会返回一个true。

2.check函数碰到return函数就结束了。此时就不会统计第二个2了


解决方案:

可以写成int函数,可以将一个2返回1,两个2返回2,三个二返回3......

但是不如直接写main函数。

#include<iostream>
using namespace std;
int main()
{
    int sum = 0, j;
    for(int i = 1; i <= 2020; ++i) {
        j = i;
        while(j / 10) {
            if(j % 10 == 2)
                sum += 1;
            j /= 10;
        }
        if(j % 10 == 2) sum += 1;
    }
    cout<<sum;
    return 0;
}

新知识:

知识点:

①bool:只能用来存放两个值:true (1) 和 false (0) 

②bool函数的简单使用

bool check(int n){
    while(n){
        int num=n%10;    //获取最低位的数字       
        if(num==2)
            return true;              
        n/=10;        //移除最低位的数字
    }                 //也就是遍历??
    return false;
}

函数碰到return函数就结束了 


其它例题:蓝桥杯2019 平方和 

注:是由此题学会的这个bool函数(虽然再用的时候写错了,且用不到bool函数)


代码:

#include <iostream>
using namespace std;
typedef  int longlong;   //这里用longlong防止结果溢出
bool check(int n){
    while(n){
        int m=n%10;              //遍历各个位数        
        if(m==0||m==1||m==2||m==9)
            return true;
        n/=10;
    }
    return false;
}
 
signed main(){
    int sum=0;
    for(int i=1;i<=2019;i++){
        if(check(i))
            sum+=i*i;
    }
    cout<<sum;
    return 0;
}

这道题是,含有“2”“0”“1”“9”结果就是“是”,不含有就是“否”。因此可以用bool


第二个:next_permutation()全排列的使用

例题一:幻方填空

幻方填空

幻方是把一些数字填写在方阵中,使得行、列、两条对角线的数字之和都相等。

欧洲最著名的幻方是德国数学家、画家迪勒创作的版画《忧郁》中给出的一个4阶幻方

他把1,2,3,...16 这16个数字填写在4 x 4的方格中。

如图所示,即:

16  ?   ?   13

?   ?   11  ?

9   ?   ?   *

?   15  ?   1

表中有些数字已经显露出来,还有些用?和*代替。

请你计算出?和*所代表的数字。

解析:

暴力枚举,全排列,用计算机最终生成需要的结果

答案:

#include<iostream>
#include<algorithm>

using namespace std;

int a[10] = {2, 3, 4, 5, 6, 7, 8, 10, 12, 14};
int f(int a[]){
	// 计算每一行的和
	int h1 = 29 + a[0] + a[1];
	int h2 = 11 + a[2] + a[3] + a[4];
	int h3 = 9 + a[5] + a[6] + a[7];
	int h4 = 16 + a[8] + a[9];
	// 计算每一列的和
	int l1 = 25 + a[2] + a[8];
	int l2 = 15 + a[0] + a[3] + a[5];
	int l3 = 11 + a[1] + a[6] + a[9];
	int l4 = 14 + a[4] + a[7];
	//计算两对角线的和
	int x1 = 24 + a[5] + a[8];
	int x2 = 17 + a[3] + a[6];
	//如果满足要求输出
	if(h1 == h2 && h2 == h3 && h3 == h4 && l1 == l2 && l2 == l3 && l3 == l4 && x1 == x2)
	cout << a[1] << endl<<a[2]<<endl<<a[3]<<endl<<a[4]<<endl<<a[5]
<<endl<<a[6]<<endl<<a[7]<<endl<<a[8]<<endl<<a[9]<<a[10]<<endl;
}
	
int main(){
	do
	{
		f(a);
	}while(next_permutation(a, a + 10)); // 利用函数枚举所有可能情况
	return 0;
}	

关于函数next_permutation()的简介:

将给定区间的数组、容器全排列
将给定区间的数组全排列。

所在头文件:#include< algorithm >

函数功能:判断所给序列中是否还有下一个全排列(即字典序的下一个)

形参:数组的起始指针和结尾的后一个指针

返回值:如果有下一个排列则返回true, 否则返回false


 如:

#include<iostream>
#include<algorithm>
using namespace std;
int main() {  
	int a[3] = {1,2,3};
	do{
		cout<<a[0]<<a[1]<<a[2]<<endl; 
	}while(next_permutation(a,a+3));	//输出1、2、3的全排列 
	
	return 0;
 } 

输出:
123
132
213
231
312
321

例题二: 三羊献瑞

代码:

#include<iostream>
#include<algorithm>
using namespace std;
/* A0 A1 A2 A3
   A4 A5 A6 A1
   A4 A5 A2 A1 A7  */
//先判断需要有多少数进行全排列,然后塞进数组
int a[10]={0,1,2,3,4,5,6,7,8,9};  

int main(){
    int sum1=0,sum2=0,sum3=0;
    while(next_permutation(a,a+10)){
        if(a[0]!=0&&a[4]!=0){//减少运算,同时避免三位数符合条件的可能
            sum1=a[0]*1000+a[1]*100+a[2]*10+a[3];
            sum2=a[4]*1000+a[5]*100+a[6]*10+a[1];
            sum3=a[4]*10000+a[5]*1000+a[2]*100+a[1]*10+a[7];
            if(sum1+sum2==sum3){
                cout << a[4] << a[5] << a[6] << a[1];
                break;//一旦找到满足条件的数字组合,就停止继续搜索其他的排列。
            }
        }
    }
    return 0;
}

第三个:求两个数的最大公约数方法

以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数

非递归代码: 

int com(int a,int b){
    int temp;
    while(a%b){
        temp=b;
        b=a%b;
        a=temp;
    }
    return b;
}

递归代码:

#include<stdio.h>
int gcd(int a,int b){
    int r=a%b;
    if(r==0){
        return b;  //出口
    }
    else{
        return gcd(b,r);//变成了求b和r的最大公约数
    }
}
int main(){
    int a,b;
    scanf("%d",&a);
    scanf("%d",&b);
    int g = gcd(a,b);
    printf("%d\n",g);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值