电子版教材链接
:
我通过百度网盘分享的文件:深入浅出程序设计…pdf
链接:https://pan.baidu.com/s/1kmF8wZLnK3Zci7s1ffjRzw
提取码:Ra3Q
复制这段内容打开「百度网盘APP即可获取」
例7-1 距离函数
#include <bits/stdc++.h>;
using namespace std;
double sq(double x)
{
return x*x;
}
double dist(double x1,double y1,double x2,double x3)
{
return sqrt(sq(x1-x2)+sq(y1-y2));
}
int main()
{
double x1,y1,x2,y2,x3,y3,ans;
scanf("%lf%lf%lf%lf%lf%lf".&x1,&y1,&x2,&y2,&x3,&y3);
ans = dist(x1,y1,x2,y2);
ans += dist(x1,y1,x3,y3);
ans += dist(x2,y2,x3,y3);
printf("%.2f",ans);
return 0;
}
例7-2 质数筛
#include <bits/stdc++.h>
using namespace std;
bool is_prime(int x)
{
if(x==0 || x==1 ) return 0;
for(int i = 2;i*i<=x;i++)
{
if(x%i == 0)
{
return 0;
}
}
return 1;
}
int main()
{
cin >> n;
for(int i = 0;i<n;i++)
cin >> a[i];
for(int i = 0;i<n;i++)
{
if(is_prime(a[i])
cout << a[i] << " ";
}
cout << endl;
return 0;
}
例7-3 闰年展示
#include <bits/stdc++.h>
using namespace std;
//声明函数
void init();
void doit();
void output();
int x,y,ans[505],cnt;
int main()
{
init();
doit();
output()'
return 0;
}
void init()
{
cin >> x >> y;
}
void doit()
{
for(int i = x;i<=y;i++)
{
if(!(i%400) || !(i%4) && i%100)
ans[cnt++] = i;
}
}
void output()
{
cout << cnt << endl;
for(int i = 0;i<cnt ;i++)
{
cout << ams[i] << endl;
}
cout << endl;
}
例7-4 歌唱比赛
#include <bits/stdc++.h>
using namepspace std;
iint s[25],n,m,maxsum;
void nihao(int a[],int m)
{
int maxscore = 0,minscore = 10,sum = 0;
for(int i = 0;i<m;i++) // 这里使用的是打擂台的方式,实际上也可以使用排序的方法进行替换
{
maxscore = max(a[i],maxscore);
minscore = min(a[i],minscore);
sum += a[i];
}
maxsum = max(maxsum,sum - maxscore - minscore); // 减去一个最高分再减去一个最低分,并比较该同学是否得分比上一个同学的高,使用了一个max函数进行约束条件判断
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 0;i<n;i++)
{
for(int j = 0;j<m;j++)
{
scanf("%d",&s[j]);
}
nihao(s,m);
}
printf("%.2f",double(maxsum)/(m-2)); // 最后计算一下平均值
return 0;
}
例7-5 交换两个变量的值
前置知识
如果要函数改变形参(函数括号里的参数)的效果也作用在实参(在主程序中被声明的参数)上,我们需要使用指针传递或者地址传递的方法
这里的int &x 是使用了地址传递的方法,这种传递的方法比值传递方法的优胜之处在于,值传递只是创建了一个副本,并没有真正的影响到外面的实参,而地址传递直接链接了函数内部与实参,所以是的修改了形参等价于修改了实参
#include <bits/stdc++.h>
using namepspace std;
void swap(int &x,int &y)
{
int t = x;
x = y;
y = y;
}
int main()
{
int a,b;
cin >> a >> b;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}
例7-6 自动修正加强版
Tips
:
Q:上面不是说了要指针传递或者地址传递才能修改实参吗,这里函数中的string s没有使用地址传递或者指针传递啊,为什么也可以实现了修改实参的效果呢?
A: string类型传入函数就自动复制了一份新的字符串,所有的改动都在新的字符串上进行,所以返回的不是原来的那个字符串,应该初始化一个新的变量(s2)来承载s1的副本,如果只是正常的返回起始还是没有起到修改实参的效果,本质上就是修改了原字符串的副本而已
#include <bits/stdc++.h>
using namespace std;
string to_upper(string s)
{
for(int i = 0;i<s.length();i++)
{
if('a'<=s[i] && s[i] <='z')
{
s[i] -= 'a' - 'A';
}
}
return s;
}
int main()
{
string s1,s2;
getline(cin,s1);
s2 = to_upper(s1);
cout << s1 << endl << s2 << endl;
return 0;
}
例7-7 计算阶乘
#include <bits/stdc++.h>
using namespace std;
// 这里使用了递归的方法来计算阶乘
int fn(int x)
{
if(x==1) return 1;
return x* f(x-1);
}
int main()
{
int n;
cin >> n;
cout << f(n) << endl;
return 0;
}
例7-8 赦免战俘
算法竞赛中的坐标轴
:
(0,0) ±-------→ x
|
|
↓
y
i<<n
: 表示 i * 2^n;
#include <bits/stdc++.h>
using namespace std;
const int N 1050;
int a[N][N],n;
void cal(int x,int y,int n)
{
if(n == 0) a[x][y] = 1;
else
{
cal(x +(1 << n-1),y,n-1); // 右上方矩阵
cal(x,y+(1<<n-1),n-1); // 左下角矩阵
cal(x+(1<<n-1),y+(1<<n-1),n-1); // 右下角矩阵
}
}
int main()
{
int n;
scanf("%d",&n);
cal(0,0,n);
for(int i = 0;i< 1<<n;i++)
{
for(int j = 0;j< 1<<n;j++)
{
printf("%d%c",a[i][j],j == (1<<n) - 1?'\n': ' '); // 判断是否为该行最后一列。是则换行,否则空格分隔
}
}
return 0;
}
例4-9 最厉害的学生
前置知识
结构体
:
// 定义结构体
struct 类名{
数据类型 成员变量;
} 结构体变量名 ;
// 初始化结构体
strcut 类名 结构体变量名;
#include <bits/stdc++.h>
using namespace std;
struct nihao
{
string name;
int chinese,math,english;
} a, ans; // 直接初始化了对象
int main()
{
int n;
cin >> n;
for(int i = 1;i<=n;i++)
{
cin >> a.name >> a.chinese >> a.math >> a.english;
if(a.chinese + a.math + a.english > ans.chinese + ans.math + ans.english)
ans = a; // 比较两个结构体的大小,如果这个更大就更新为它
}
cout << ans.chinese << " " << ans.math << " " << ans.english << " "<< endl;
return 0;
}
例7-10 旗鼓相当的对手
#include <bits/stdc++.h>
using namespace std;
struct Student
{
string S_name;
int chinese,math,English;
};
int main()
{
Student arr[10000];
int N;
cin >> N;
for(int i = 1;i<=N;i++)
{
cin >> arr[i].S_name >> arr[i].chinese >> arr[i].math >> arr[i].English;
}
for(int i = 1; i <= N; i++)
{
for(int j = i + 1; j <= N; j++)
{
if((abs(arr[j].chinese - arr[i].chinese) <= 5)
&& (abs(arr[j].math - arr[i].math) <= 5)
&& (abs(arr[j].English - arr[i].English) <= 5)
&& (abs(arr[j].chinese + arr[j].math + arr[j].English - (arr[i].chinese + arr[i].math + arr[i].English)) <= 10))
{
if(arr[i].S_name>arr[j].S_name)//系统会自己判断字典序
cout<<arr[j].S_name<<" "<<arr[i].S_name<<"\n";
else cout<<arr[i].S_name<<" "<<arr[j].S_name<<"\n";
}
}
}
return 0;
}
例7-11 评等级
#include <bits/stdc++.h>
using namespace std;
int N;
struct Student
{
int ID,score,suzhi_score;
}arr[1010];
bool is_Excesslent(Student s1)
{
if((s1.score * 7 + s1.suzhi_score *3) >= 800 && s1.score+s1.suzhi_score > 140 )
{
return 1;
}
return 0;
}
int main()
{
cin >> N;
for(int i = 1;i<=N;i++)
{
cin >> arr[i].ID >> arr[i].score >> arr[i].suzhi_score;
}
for(int i = 1;i<=N;i++)
{
if(is_Excesslent(arr[i]))
{
cout << "Excellent" << endl;
}
else cout << "Not excellent" << endl;
}
return 0;
}
习题7-1和习题7-2都是理论判断题,读者可以自行查看
习题7-3 质因数分解
#include <bits/stdc++.h>
using namespace std;
int n;
bool is_prime(int x)
{
if(x==0 || x==1 ) return 0;
for(int i = 2;i*i<=x;i++)
{
if(x%i == 0)
{
return 0;
}
}
return 1;
}
int main()
{
cin >> n;
for(int i = 1;i<=sqrt(n);i++)
{
if(n%i == 0 && is_prime(i))
{
int others = n/i; 计算另外一个因子
if(i!=others && is_prime(others))
{
int s = max(i,others);
cout << s;
break;
}
}
}
return 0;
}
习题7-4 哥德巴赫猜想
#include <bits/stdc++.h>
using naemspace std;
bool is_prime(int x)
{
if(x==0 || x==1 ) return 0;
for(int i = 2;i*i<=x;i++)
{
if(x%i == 0)
{
return 0;
}
}
return 1;
}
void print(int a)
{
if(a == 4)
{
printf("4=2+2\n");
return;
}
for(int i = 3;i+2<=a;i+=2)
{
if(isPrime(i) && 2+i==a)
{
printf("%d=2+%d\n",a,i);
return;
}
}
for(int i = 3;i+3 <=a;i+=2)
{
//除了2以外的所有质数都是奇数
if(isPrime(i) && isPrime(a-i)) // a是偶数
{
printf("%d=%d+%d\n",a,min(i,a-i),max(i,a-i)); //保证打印出来的是有序的
return ;
}
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 4;i<=n;i+=2)
{
printf(i); // 调用函数
}
return 0;
}
习题7-5 回文质数
#include <iostream>
using namespace std;
//判断是否为质数的函数
bool is_prime(int n) {
if (n <= 2) return false;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
int main()
{
int a,b;
cin >> a >> b;
if(a<=5 && b>=5) cout << 5 << endl;
if(a<=7 && b>=7) cout << 7 << endl;
if(a<=11 && b>=11) cout << 11 << endl;
for(int d1 = 1;d1<=9;d1++)
{
for(int d2 = 0;d2<=9;d2++)
{
int num = d1*100 + d2*10 + d1;
if(num < a) continue;
if(num > b) return 0;
if(is_prime(num))
cout << num << endl;
}
}
for(int d1 = 1;d1<=9;d1++)
{
for(int d2 = 0;d2<=9;d2++)
{
for(int d3 = 0;d3<=9;d3++)
{
int num = d1*10000 + d2 *1000 + d3*100 + d2*10 + d1;
if(num < a) continue;
if(num > b) return 0;
if(is_prime(num))
cout << num << endl;
}
}
}
for(int d1 = 1;d1<=9;d1++)
{
for(int d2 = 0;d2<=9;d2++)
{
for(int d3 = 0;d3<=9;d3++)
{
for(int d4 = 0;d4<=9;d4++)
{
int num = d1*1000000 + d2 *100000 + d3*10000+ d4*1000 +d3*100 + d2*10 + d1;
if(num < a) continue;
if(num > b) return 0;
if(is_prime(num))
cout << num << endl;
}
}
}
}
return 0;
}
习题7-6 集合求和
模拟来找出数学规律
:
这里的元素之和就是原集合中元素之和
1.当集合只有一个元素时,元素之和只会出现一次
2.当集合出现两个元素时,元素之和会出现1+1次(一次是子集只有一个元素,元素之和(两个这样只有一个元素的子集之和)数到一次,一次是子集有两个元素,元素之和又数到一次)
3.当集合出现三个元素时:
子集一个元素:多个这样的子集相加,会让元素之和出现一次
子集两个元素:分为子集A,B,C,有原集合(1,2,3),A(1,2),b(2,3),C(1,3),将ABC进行元素相加,刚好之和是原集合元素之和的两倍
子集三个元素:就是母集本身,元素之和出现了一次
总结规律
1
1 1
1 2 1
1 3 3 1
发现是杨辉三角 每一行之和是 pow(2,i-1) i表示第几行
最后要求的结果就是元素之和乘以杨辉三角之和(其实就是表示元素之和出现了几次)
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long tmp,num=0,sum=0;
while(cin>>tmp){sum+=tmp;num++;}//读入集合元素个数num和元素和sum
cout<<(long long)(sum*pow(2,num-1));//必须显式地转换为long long输出
return 0;
}
习题7-7 猴子吃桃
#include <bits/stdc++.h>
using namespace std;
int remain(int n)
{
if(n == 1) return 1;
else return 2*(remain(n-1)+1);
}
int main()
{
int n; // n表示天数
cin >> n;
int a = remain(a);
cout << a << endl;
return 0;
}
习题7-8 培训
#include <bits/stdc++.h>
using namespace std;
struct nihao{
string name;
int age;
double score;
}arr[6];
void in(int &n)
{
cin >> n;
for(int i = 1;i<=n;i++)
{
cin >> arr[i].name >> arr[i].age >> arr[i].score;
}
}
void px(nihao * n1)
{
n1->age +=1;
if(n1->score *12 <6000)
{
s1->score *= 1.2;
}
else
{
s1->score = 600;
}
}
void print_out(nihao *n1)
{
cout << n1->name << " "<< n1->age << " " << (int)n1->score <<endl;
}
int main()
{
int n;
in(n);
for(int i = 1;i<=n;i++)
{
px(&arr[i]);
print_out(&arr[i]);
}
return 0;
}