有没有大神帮忙指导一下新人,感谢!!
第一个: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;
}