北大郭炜慕课程序设计与算法(一)C++的OpenJudge题目答案
- 学习心得
- 题目答案
- 001 输出第二个整数
- 002 字符菱形
- 003 打印ASCII码
- 004 打印字符
- 005 整型数据类型存储空间大小
- 006 浮点型数据类型存储空间大小
- 007 对齐输出
- 008 输出保留12位小数的浮点数
- 009 空格分隔输出
- 010 计算球的体积
- 011 大象喝水
- 012 奇偶数判断
- 013 求一元二次方程的根
- 014 点和正方形的关系
- 015 苹果和虫子2
- 016 简单计算器
- 017 求整数的和与均值
- 018 整数序列的元素最大跨度值
- 019 奥运奖牌计数
- 020 乘方计算
- 021 鸡尾酒疗法
- 022 角谷猜想
- 023 正常血压
- 024 数字反转
- 025 求特殊自然数
- 026 雇佣兵
- 027 数字统计
- 028 与指定数字相同的数的个数
- 029 陶陶摘苹果
- 030 年龄与疾病
- 031 校门外的树
- 032 计算鞍点
- 033 图像模糊处理
- 034 矩阵转置
- 035 Pell数列
- 036 求最大公约数问题
- 037 编程填空:第i位替换
- 038 编程填空:第i位取反
- 039 编程填空:左边i位取反
- 040 统计数字字符个数
- 041 找第一个只出现一次的字符
- 042 石头剪子布
- 043 最长最短单词
- 044 密码翻译
- 045 指针练习:输出Hello
- 046 指针练习:输出Tesla
- 047 指针练习:ForEach
- 048 指针练习:Memcpy之一
- 049 指针练习:double
- 050 指针练习:Memcpy之二
- 051 指针练习:MyMax
- 052 指针练习:指向指针的指针
- 053 指针练习:SwapMemory
- 054 成绩排序
- 055 分数线划定
- 056 病人排队
- 057 mysort
- 058 从字符串中取数
- 059 sort简单题
- 060 还是sort简单题
- 061 Set
- 062 热血格斗场
- 063 冷血格斗场
- 结语
学习心得
2022下半年学习了郭炜老师的C++课程,郭老师的教学深入浅出,尤为可贵的是能讲清楚知识的前后联系和知识的架构,此外本课程的特点是排除了C++面向对象的特性,也即不讲授所谓类、对象等概念,对初学者友好,很建议新手自学本课,课程链接如下:北大郭炜慕课程序设计与算法(一)。
OpenJudge题目的链接是:OpenJudge题目。下面会展示我所做的题目的答案
,以及一些针对题目和概念的心得
。
做题时参考了虾米不打烊的文章,链接如下:虾米不打烊的文章。
题目答案
001 输出第二个整数
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int a;int b;int c;
scanf("%d%d%d",&a,&b,&c);
printf("%d",b);
return 0;
}
002 字符菱形
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
char a;
scanf("%c",&a);
printf(" %c \n",a);
printf(" %c%c%c \n",a,a,a);
printf("%c%c%c%c%c\n",a,a,a,a,a);
printf(" %c%c%c \n",a,a,a);
printf(" %c \n",a);
return 0;
}
003 打印ASCII码
cin、cout输出会比上面所用的scanf和printf更方便,速度也更快,并且可以操作符重载。
#include<iostream>
#include<cstring>
using namespace std;
int main(){
char a;int b;
cin>>a;
b=a;
cout<<b<<endl;
return 0;
}
004 打印字符
#include<iostream>
#include<cstring>
using namespace std;
int main(){
char a;int b;
cin>>b;
a=b;
cout<<a<<endl;
return 0;
}
005 整型数据类型存储空间大小
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int a;short b;
cout<<sizeof(a)<<" "<<sizeof(b);
return 0;
}
006 浮点型数据类型存储空间大小
sizeof是重要的,后面对于复杂的数据类型我们会常用到。
#include<iostream>
#include<cstring>
using namespace std;
int main(){
float a;double b;
cout<<sizeof(a)<<" "<<sizeof(b);
return 0;
}
007 对齐输出
用cout格式化输出有很多特性,除此以外还有ostream 类的成员方法。
#include<iostream>
//#include<cstdio> //使用scanf和printf需要加入cstdio库
#include<cstring>
#include <iomanip>
using namespace std;
int main() {
int a; int b; int c;
cin >> a >> b >> c;
/*
cout.width(8);
cout.setf(ios::right);
cout << a <<" " << b<<" " << c;
*/
cout << setw(8) << a << ' ' << setw(8) << b << ' ' << setw(8) << c << endl;
return 0;
}
008 输出保留12位小数的浮点数
#include<iostream>
//#include<cstdio> //使用scanf和printf需要加入cstdio库
#include<cstring>
using namespace std;
int main() {
double a;
cin >> a;
//精度是指小数点位数
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(12);
cout << a ;
return 0;
}
009 空格分隔输出
#include<iostream>
//#include<cstdio> //使用scanf和printf需要加入cstdio库
#include<cstring>
#include <iomanip>
using namespace std;
int main() {
char a; int b; float c; double d;
cin >> a >> b >> c>>d;
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(6);
cout << a << " " << b << " " <<c<<" "<<d;
return 0;
}
010 计算球的体积
注意在计算时变量的数据类型转换。
#include<iostream>
//#include<cstdio> //使用scanf和printf需要加入cstdio库
#include<cstring>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
double V; double r;
#define pi 3.14
cin >> r;
V = 4.0 / 3.0 * pi * pow(r, 3);
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(2);
cout<<V;
return 0;
}
011 大象喝水
多种舍入规则对应不同的函数。
#include<iostream>
#include<cstring>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int h; int r;
double V;
int n;
#define pi 3.14159
cin >> h>>r;
V = pi *h* pow(r, 2)/1000;
n = ceil(20/V);
cout << n;
return 0;
}
012 奇偶数判断
#include<iostream>
#include<cstring>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int n;
cin >> n;
if (n % 2)
{
cout << "odd";
}
else {
cout << "even";
}
return 0;
}
013 求一元二次方程的根
#include <iostream>
#include <cstring>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
double a; double b; double c;
double x1; double x2;
double real; double imaginary;
cin >> a >> b >> c;
x1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
x2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
if (b == 0)real = 0;
else
real = -1 * (b / (2 * a));
imaginary = sqrt(4 * a * c - b * b) / (2 * a);
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(5);
if (pow(b,2)==4*a*c){
cout << "x1=x2=" << x1;
}
else if (pow(b, 2) > 4 * a * c){
cout << "x1=" << x1 << ";" << "x2=" << x2;
}
else if(pow(b, 2) < 4 * a * c){
cout << "x1=" << real << "+"<<imaginary<<"i" << ";" << "x2=" << real << "-" << imaginary <<"i";
}
return 0;
}
014 点和正方形的关系
#include <iostream>
#include <cstring>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int x; int y;
cin >> x >> y;
if (abs(x) <= 1 && abs(y) <= 1)
cout << "yes";
else
cout << "no";
return 0;
}
015 苹果和虫子2
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
int n; int x; int y; int r;
cin >>n>> x >> y;
r = n - ceil(y * 0.1 / (x * 0.1));//一种转换方法
if (r <= 0)
cout << 0;
else
cout << r;
return 0;
}
016 简单计算器
使用ASCii码。
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
int a; int b; char o;
cin >> a >> b >> o;
if (o != 42 && o != 43 && o != 45 && o != 47)
cout << "Invalid operator!";
else
switch (o) {
case 42:
cout << a * b;
break;
case 43:
cout << a + b;
break;
case 45:
cout << a - b;
break;
case 47:
if (b == 0) {
cout << "Divided by zero!";
break;
}
else {
cout << a / b;
break;
}
}
return 0;
}
017 求整数的和与均值
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
int n; int x; int sum;
sum = 0;
cin >> n;
for (int i = 0; i <= n - 1; ++i) {
cin >> x;
sum += x;
}
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(5);
cout << sum <<" "<< sum * 0.1 / (n * 0.1);
return 0;
}
018 整数序列的元素最大跨度值
找最大最小值。
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
int n; int x; int max; int min;
max = 0;
min = 1000;
cin >> n;
for (int i = 0; i <= n - 1; ++i) {
cin >> x;
if (x > max)
max = x;
if (x < min)
min = x;
}
cout << max-min;
return 0;
}
019 奥运奖牌计数
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
int n; int gold; int sliver; int copper;
int sg; int ss; int sc;
sg = 0;
ss = 0;
sc = 0;
cin >> n;
for (int i = 0; i <= n - 1; ++i) {
cin >> gold>>sliver>>copper;
sg += gold;
ss += sliver;
sc += copper;
}
cout << sg<<" "<<ss<<" "<<sc<<" "<< sg + ss + sc;
return 0;
}
020 乘方计算
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int a, n;
int result = 1;
cin >> a >> n;
for (int i = 1; i <= n; ++i)
result *= a;
cout << result;
return 0;
}
021 鸡尾酒疗法
使用数组。
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int n; int x, y;
double therapy[20] = { 0 }, cocktail = 0; int flag[20] = { 0 };
int count = 0;
cin >> n;
for (int i = 0; i <= n - 1; ++i){
cin >> x >> y;
++count;//if cin.get....
if (count == 1) {
cocktail = double(y) / double(x);//y * 0.1 / (x * 0.1)
}
else {
therapy[i] = double(y) / double(x);
}
if (therapy[i] - cocktail > 0.05)
flag[i] = 1;
else if ( cocktail - therapy[i] > 0.05)
flag[i] = 2;
else
flag[i] = 3;
}
for (int i = 1; i <= n - 1; ++i) {
if(flag[i] == 1)
cout << "better"<<endl;
else if (flag[i] == 2)
cout << "worse" << endl;
else if(flag[i] == 3)
cout << "same" << endl;
}
return 0;
}
022 角谷猜想
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
long n;
cin >> n;
while (n != 1) {
if (n % 2 != 0) {
n = n * 3 + 1;
cout << n/3 << "*3+1=" << n<<endl;
}
else {
n = n / 2;
cout << n*2<< "/2=" << n<<endl;
}
}
cout << "End";
return 0;
}
023 正常血压
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int n; int x, y;
int count = 0;
int maxcount = 0;
cin >> n;
for (int i = 0; i <= n - 1; ++i) {
cin >> x >> y;
if (x >= 90 && x <= 140 && y >= 60 && y <= 90) {
++count;
if(maxcount<=count)
maxcount = count;
}
else
count = 0;
}
cout << maxcount;
return 0;
}
024 数字反转
做题时有一些思考,写在注释中。
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
//必须得知道n的范围
//int n,a,b,c;
//cin >> n;
//a = n % 10;
//b = n / 10 % 10;
//c = n / 100;
//其实还是得知道a的位数
int a, b=0;
cin >> a;
while (a) {
b = b * 10 + a % 10;
a = a / 10;
}
cout << b;
return 0;
}
025 求特殊自然数
# include<iostream>
using namespace std;
//这个数一定在81-342范围里
int main()
{
for (int i = 81; i < 343; i++) {
//转为7进制
int j = i;
int yushu11 = j % 7;
j = j / 7;
int yushu12 = j % 7;
j = j / 7;
int yushu13 = j % 7;
j = j / 7;
//转为9进制
j = i;
int yushu21 = j % 9;
j = j / 9;
int yushu22 = j % 9;
j = j / 9;
int yushu23 = j % 9;
j = j / 9;
//看是不是相反的关系
if (yushu11 == yushu23 && yushu12 == yushu22 && yushu13 == yushu21) {
cout << i<<endl;
cout << yushu13 << yushu12 << yushu11<<endl;
cout << yushu23 << yushu22 << yushu21<<endl;
}
//是就输出,再找找后面的
}
return 0;
}
026 雇佣兵
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int m, n, x,count=0;
cin >> m >> n >> x;
//按照 开始每个战斗期时 有无能量元素
while (x*n >= m) {
++count;
x -= ceil(double(m) / double(n));
if (m >= n)
n += floor(m / n);
}
cout << n;
return 0;
}
027 数字统计
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int l, r; int x ;
int count = 0;
cin >> l >> r;
for (int i = l; i <= r; ++i) {
x = 1;
while (1) {
if ((i / x) % 10 == 2) {
++count;
}
x *= 10;
if (i / x == 0)
break;
}
}
cout << count;
return 0;
}
028 与指定数字相同的数的个数
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int n, m,count=0;
cin >> n;
int* a = new int[n];
for (int i = 0; i <= n - 1; ++i) {
cin >> a[i];
}
cin >> m;
for (int i = 0; i <= n - 1; ++i) {
if (a[i] == m)
++count;
}
cout << count;
return 0;
}
029 陶陶摘苹果
#include<iostream>
using namespace std;
int main() {
int a[10], b, count = 0;
for (int i = 0; i <= 9; ++i)
cin >> a[i];
cin >> b;
for (int i = 0; i <= 9; ++i)
if (a[i] - b - 30 <= 0)
++count;
cout << count;
return 0;
030 年龄与疾病
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int n; int aa = 0, bb = 0, cc = 0, dd = 0;
int age[100];
cin >> n;
for (int i = 0; i <= n - 1; ++i)
cin >> age[i];
for (int i = 0; i <= n - 1; ++i) {
if (age[i] > 0 && age[i] <= 18)
++aa;
else if(age[i] >= 19 && age[i] <= 35)
++bb;
else if (age[i] >= 35 && age[i] <= 60)
++cc;
else
++dd;
}
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
cout << double(100 * aa) / n << "%" << endl;
cout << double(100 * bb) / n << "%" << endl;
cout << double(100 * cc) / n << "%" << endl;
cout << double(100 * dd) / n << "%" << endl;
return 0;
}
031 校门外的树
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int l, m; int low, up; int count = 0;
int a[10001] = {0};
cin >> l >> m;
for (int i = 0; i <= m - 1; ++i) {
cin >> low >> up;
for (int j = low; j <= up; ++j) {
a[j] = 1;//直接计数也可,但可能会遇到重复的区域
}
}
for (int k = 0; k <= 10000; ++k)
count += a[k];
cout << l+1-count;
return 0;
}
032 计算鞍点
用到了memset对数组初始化。
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int rmax[5], cmin[5] = { 1000000,1000000 ,1000000 ,1000000 ,1000000 };
memset(rmax, 0, sizeof(rmax));
int t = 4;
int a[5][5];
for (int i = 0; i <= 4; ++i) {
for (int j = 0; j <= 4; ++j) {
cin >> a[i][j];
}
}
for (int i = 0; i <= 4; ++i) {
for (int j = 0; j <= 4; ++j) {
if (a[i][j] > rmax[i])
rmax[i] = a[i][j];
if (a[i][j] < cmin[j])
cmin[j] = a[i][j];
}
}
for (int i = 0; i <= 4; ++i) {
for (int j = 0; j <= 4; ++j) {
if (a[i][j] == rmax[i] && a[i][j] == cmin[j]) {
cout << i+1 << " " << j+1 << " " << a[i][j];
--t;
}
}
}
if (t == 4)
cout << "not found";
return 0;
}
033 图像模糊处理
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int n, m;
int a[100][100]; int b[100][100];//一定要新建一个矩阵,否则计算过程中就会迭代结果
cin >> n >> m;
for (int i = 0; i <= n-1; ++i) {
for (int j = 0; j <= m-1; ++j) {
cin >> a[i][j];
b[i][j] = a[i][j];
}
}
for (int i = 1; i <= n - 2; ++i) {
for (int j = 1; j <= m - 2; ++j) {
b[i][j]= round((double(a[i][j])+double(a[i-1][j])+ double(a[i+1][j])+ double(a[i][j-1])+ double(a[i][j+1]))*0.20);
}
}
for (int i = 0; i <= n - 1; ++i) {
for (int j = 0; j <= m - 1; ++j) {
cout<<b[i][j]<<" ";
while (j == m - 1) {
cout << endl;
break;
}
}
}
return 0;
}
034 矩阵转置
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
int n, m;
int a[100][100]; int b[100][100];
cin >> n >> m;
for (int i = 0; i <= n - 1; ++i) {
for (int j = 0; j <= m - 1; ++j) {
cin >> a[i][j];
b[j][i] = a[i][j];
}
}
//考虑向量的情况
if (n == 1) {//别忘了是==
for (int i = 0; i <= m - 1; ++i) {
cout << b[i][0] << endl;
}
}
else if (m == 1) {
for (int i = 0; i <= n - 1; ++i) {
cout << b[0][i] << " ";
}
}
//矩阵情况
else {
for (int i = 0; i <= m - 1; ++i) {
for (int j = 0; j <= n - 1; ++j) {
cout << b[i][j] << " ";
while (j == n - 1) {
cout << endl;
break;
}
}
}
}
return 0;
}
035 Pell数列
#include <bits/stdc++.h>
using namespace std;
int b[1000001]; //提前计算出数列每一项的值
int main() {
int n;
cin>>n;
int a[n];
for(int i=0; i<n; i++) {
cin>>a[i];
}
b[0]=1;
b[1]=2;
//计算数列
for(int i=2; i<=1000000; i++) {
b[i]=(2*b[i-1]+b[i-2])%32767;//利用高精度思想,每次计算后都取模
}
for(int i=0; i<n; i++) {
cout<<b[a[i]-1]<<endl;//输出第i位的值,由于数列下标从0开始,要减1
}
}
036 求最大公约数问题
调用函数。
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int commonfactor(int a, int b) {
int cf; int c;
if (a % b != 0) {
c = a;
a = b;
b = c % b;
return commonfactor(a, b);
}
if (a % b == 0)
return b;
}
int main() {
int a, b, c;
cin >> a>> b;
if (b < a) {
c = a;
a = b;
b = c;
}
cout << commonfactor(a, b);
return 0;
}
037 编程填空:第i位替换
#include <iostream>
using namespace std;
int bitManipulation1(int n, int m, int i) {
return n - (n & (1 << i)) + (m & (1 << i));
}
int main() {
int n, m, i, t;
cin >> t;
while (t--) {
cin >> n >> m >> i;
cout << bitManipulation1(n, m, i) << endl;
}
return 0;
}
038 编程填空:第i位取反
#include <iostream>
using namespace std;
int bitManipulation2(int n, int i) {
return (1 << i) ^ n;
}
int main() {
int t, n, i;
cin >> t;
while (t--) {
cin >> n >> i;
cout << bitManipulation2(n, i) << endl;
}
return 0;
}
039 编程填空:左边i位取反
#include <iostream>
using namespace std;
int bitManipulation3(int n, int i) {
return (-1 << (32-i)) ^ n;
}
int main() {
int t, n, i;
cin >> t;
while (t--) {
cin >> n >> i;
cout << bitManipulation3(n, i) << endl;
}
return 0;
}
040 统计数字字符个数
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main(){
char a[10000];
int n; int count = 0;
cin.getline(a, sizeof(a));
n = strlen(a);
for (int i = 0; i <= n - 1; ++i) {
if (a[i] >= int('0') && a[i] <= int('9'))
++count;
}
cout << count;
return 0;
}
041 找第一个只出现一次的字符
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int main() {
char a[100000]; int n; char the;
int count = 0;
cin >> a;
n = strlen(a);
for (int i = 0; i <= n - 1; ++i) {
count = 0;//每次找前置0
for (int j = 0 ; j <= n - 1; ++j) {
if (a[i] == a[j]) {
++count ;//找到就是非0
}
}
//cout << count<<endl;
if (count==1) {
cout << a[i];
return 0;
}
}
cout << "no";
}
042 石头剪子布
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
int caiquan(string a,string b) {
if (a == "Rock" && b == "Scissors" || a == "Scissors" && b == "Paper" || a == "Paper" && b == "Rock") {//strcmp
return 1;
}
else if (b == "Rock" && a == "Scissors" || b == "Scissors" && a == "Paper" || b == "Paper" && a == "Rock") {
return 2;
}
else
return 3;
}
int main() {
int n; char a[101]; char b[101]; int c[101];
cin >> n;
for (int i = 0; i <= n - 1; ++i) {
cin >> a >> b;
c[i]= caiquan(a, b);
}
for (int i = 0; i <= n - 1; ++i) {
if (c[i] == 1)
cout << "Player1" << endl;
else if (c[i] == 2)
cout << "Player2" << endl;
else if (c[i] == 3)
cout << "Tie" << endl;
}
return 0;
}
043 最长最短单词
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
//如果用cin和scanf读入字符串数组,会读入到空格为止
int main(){
char a[10000];
int len_min=300,len_max=0;
int pos_min,pos_max;
int count=0;
cin.getline(a,sizeof(a));
a[strlen(a)]=' ';//最后一位置为空格,否则遇到一个单词组成的句子将无法判断
for(int i=0;a[i];++i){
if(a[i]!=' '&&a[i]!=',')
++count;
else if(count!=0){//要加非零的条件,否则每次都自动置零
if(count<len_min){
len_min=count;
pos_min=i-count;//记录最短单词起始位置
}
if(count>len_max){
len_max=count;
pos_max=i-count;//记录最长单词起始位置
}
count=0;
}
}
for(int i=pos_max;i<=pos_max+len_max-1;++i){
cout<<a[i];
}
cout<<endl;
for(int i=pos_min;i<=pos_min+len_min-1;++i){
cout<<a[i];
}
return 0;
}
044 密码翻译
#include <iostream>
#include <cstdio> //使用scanf和printf需要加入cstdio库
#include <cstring>
#include <iomanip>//setw
#include <cmath>
using namespace std;
//如果用cin和scanf读入字符串数组,会读入到空格为止
int main(){
char a[100];
int count=0;
cin.getline(a,sizeof(a));
for(int i=0;a[i];++i){
if((int(a[i])>=65&&int(a[i])<=89)||(int(a[i])>=97&&int(a[i])<=121))
a[i]=char(a[i]+1);
else if(int(a[i])==90||int(a[i])==122)
a[i]=char(a[i]-25);
}
for(int i=0;a[i];++i){
cout<<a[i];
}
return 0;
}
045 指针练习:输出Hello
#include <iostream>
using namespace std;
int main() {
char s[] = "Hello";
char * p;
for(
p=s;*p;p++
)
cout << * p ;
return 0;
}
046 指针练习:输出Tesla
#include <iostream>
using namespace std;
void Print(const char * p1, const char * p2)
{
for(
p1;p1<p2;++p1
)
cout << * p1;
}
int main()
{
const char * s = "Tesla123";
Print(s,s+5);
cout << endl;
Print(s,s+3);
cout << endl;
return 0;
}
047 指针练习:ForEach
函数指针。
#include <iostream>
using namespace std;
void ForEach(void * a, int width, int num,
void (*f)(void *p)
)
{
for(int i = 0;i < num; ++i)
f((char*)a+width*i);
}
void PrintSquare(void * p)
{
int * q = (int*)p;
int n = *q;
cout << n * n << ",";
}
void PrintChar(void * p) {
char * q = (char*)p;
cout << *q << ",";
}
int main()
{
int a[5] = {1,2,3,4,5};
char s[] = "hello!";
ForEach(a,sizeof(int),5,PrintSquare);
cout << endl;
ForEach(s,sizeof(char),6,PrintChar);
return 0;
}
048 指针练习:Memcpy之一
#include <iostream>
using namespace std;
void Memcpy(char * src,char * dest,int n)
{
char* pdest=dest;
char* psrc=src;
for(int i=0;i<n;++i){
*(pdest+i)=*(psrc+i);
}
}
int Strlen(char * s)
{
int i;
for( i = 0; s[i]; ++i);
return i;
}
int main()
{
int a;
char s1[30];
char s2[30];
int t;
cin >> t;
for(int i = 0;i < t; ++i) {
cin >> a;
int b = 99999999;
Memcpy((char*)&a,(char *) &b,sizeof(int));
cout << b << endl;
}
for(int i = 0;i < t; ++i) {
cin >> s1;
Memcpy(s1,s2,Strlen(s1)+1);
cout << s2 << endl;
}
return 0;
}
049 指针练习:double
#include <iostream>
using namespace std;
void Double(int * p, int n)
{
for(int i = 0;i < n; ++i)
p[i] *= 2;
}
int main()
{
int a[3][4] = { { 1,2,3,4},{5,6,7,8},
{ 9,10,11,12 } };
Double(
a[0]+4,6
);
for(int i = 0;i < 3; ++i) {
for(int j = 0; j < 4; ++j)
cout << a[i][j] << ",";
cout << endl;
}
return 0;
}
050 指针练习:Memcpy之二
#include <iostream>
using namespace std;
void Memcpy( void * src, void * dest, int size)
{
char temp[100];
for (int i = 0; i < size; i++) {
temp[i] = *((char*)src + i);
}
for (int i = 0; i < size; i++) {
*((char *)dest+i) = temp[i];
}
}
void Print(int * p,int size)
{
for(int i = 0;i < size; ++i)
cout << p[i] << ",";
cout << endl;
}
int main()
{
int a[10];
int n;
cin >> n;
for(int i = 0;i < n; ++i)
cin >> a[i];
int b[10] = {0};
Memcpy(a,b,sizeof(a));
Print(b,n);
int c[10] = {1,2,3,4,5,6,7,8,9,10};
Memcpy(c,c+5,5*sizeof(int)); //将c的前一半拷贝到后一半
Print(c,10);
char s[10] = "123456789";
Memcpy(s+2,s+4,5); //将s[2]开始的5个字符拷贝到s[4]开始的地方
cout << s << endl;
char s1[10] = "123456789";
Memcpy(s1+5,s1+1,4); //将s1[5]开始的4个字符拷贝到s1[1]开始的地方
cout << s1 << endl;
return 0;
}
051 指针练习:MyMax
#include <iostream>
using namespace std;
char* MyMax(void* a,int width,int num,int(*fun)(void * n1,void * n2)){
char* max=(char*)a;
for(int i = 0;i < num; ++i) {
if(fun(max,(char*)a+width*i)<0){
max = (char*)(a+width*i);
}
}
return max;
}
int Compare1(void * n1,void * n2)
{
int * p1 = (int * )n1;
int * p2 = (int * )n2;
return ((*p1)%10) - ((*p2)%10);
}
int Compare2(void * n1,void * n2)
{
int * p1 = (int * )n1;
int * p2 = (int * )n2;
return *p1 - *p2;
}
#define eps 1e-6
int Compare3(void * n1,void * n2)
{
float * p1 = (float * )n1;
float * p2 = (float * )n2;
if( * p1 - * p2 > eps)
return 1;
else if(* p2 - * p1 > eps)
return -1;
else
return 0;
}
int main()
{
int t;
int a[10];
float d[10];
cin >> t;
while(t--) {
int n;
cin >> n;
for(int i = 0;i < n; ++i)
cin >> a[i];
for(int i = 0;i < n; ++i)
cin >> d[i];
int * p = (int *) MyMax(a,sizeof(int),n,Compare1);
cout << * p << endl;
p = (int *) MyMax(a,sizeof(int),n,Compare2);
cout << * p << endl;
float * pd = (float * )MyMax(d,sizeof(float),n,Compare3);
cout << * pd << endl;
}
return 0;
}
052 指针练习:指向指针的指针
#include <iostream>
using namespace std;
int main()
{
int x,y,z;
x = 10;
y = 20;
z = 30;
int * a[3] = { &x, &y,&z};
for(
int **p=a;
p < a + 3; ++p)
cout<< * (*p) << endl;
return 0;
}
053 指针练习:SwapMemory
#include <iostream>
using namespace std;
void SwapMemory(void * m1,void * m2, int size)
{
char temp;
char* n1=(char*) m1;
char* n2=(char*) m2;
for(int i = 0;i < size; ++i){
temp =*(n1+i);
*(n1+i)=*(n2+i);
*(n2+i)=temp;
}
}
void PrintIntArray(int * a,int n)
{
for(int i = 0;i < n; ++i)
cout << a[i] << ",";
cout << endl;
}
int main()
{
int a[5] = {1,2,3,4,5};
int b[5] = {10,20,30,40,50};
SwapMemory(a,b,5 * sizeof(int));
PrintIntArray(a,5);
PrintIntArray(b,5);
char s1[] = "12345";
char s2[] = "abcde";
SwapMemory(s1,s2,5);
cout << s1 << endl;
cout << s2 << endl;
return 0;
}
054 成绩排序
结构数组。
#include<iostream>
using namespace std;
struct Student{
string name;
int grade;
};
int main() {
Student s[20];
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> s[i].name >> s[i].grade;
}
for (int i = 0; i < n - 1; ++i) {
int tempmax = i;
for (int j = i + 1; j < n; ++j) {
if (s[j].grade > s[tempmax].grade)
tempmax = j;
else if (s[j].grade == s[tempmax].grade) {
if (s[j].name < s[tempmax].name) {
tempmax = j;
}
}
}
Student tmp = s[i];
s[i] = s[tempmax];
s[tempmax] = tmp;
}
for (int i = 0; i < n; ++i) {
cout << s[i].name << " " << s[i].grade << endl;
}
}
055 分数线划定
可以采用其他排序方法。
#include<iostream>
using namespace std;
struct Volunteer{
string number;
int grade;
};
int main() {
Volunteer c[5000];
int n,m,p;
cin >> n >> m;
p = (int)(m*1.5);
for (int i = 0; i < n; ++i) {
cin >> c[i].number >> c[i].grade;
}
for (int i = 0; i < n - 1; ++i) {
int tempmax = i;
for (int j = i + 1; j < n; ++j) {
if (c[j].grade > c[tempmax].grade)
tempmax = j;
else if (c[j].grade == c[tempmax].grade) {
if (c[j].number < c[tempmax].number) {
tempmax = j;
}
}
}
Volunteer tmp = c[i];
c[i] = c[tempmax];
c[tempmax] = tmp;
}
for(int i = p; i < n; ++i){
if(c[i].grade == c[p-1].grade)
++p;
}
cout << c[p-1].grade << " " << p << endl;
for (int i = 0; i < p; ++i) {
cout << c[i].number << " " << c[i].grade << endl;
}
}
056 病人排队
#include<iostream>
using namespace std;
struct Patient{
string id;
int age;
int index;
};
int main() {
Patient c[100];
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> c[i].id >> c[i].age;
c[i].index = i;//通过index可以避免在使用选择排序时直接把序号交换掉
}
for (int i = 0; i < n - 1; ++i) {
int tempmin = i;
for (int j = i + 1; j < n; ++j) {
//新病人老
if(c[j].age>=60){
//在位病人老
if(c[tempmin].age>=60){
if (c[j].age > c[tempmin].age){
tempmin = j;
}
else if (c[j].age == c[tempmin].age) {
if (c[j].index < c[tempmin].index) {
tempmin = j;
}
}
}
//在位病人新
else {
tempmin = j;
}
}
//新病人新
if(c[j].age<60){
//在位病人新(在位病人老的情况无需排序)
if(c[tempmin].age<60){
if (c[j].index < c[tempmin].index) {
tempmin = j;
}
}
}
}//一定要注意这个括号的位置,对j循环结束之后再对换
Patient tmp = c[i];
c[i] = c[tempmin];
c[tempmin] = tmp;
}
for (int i = 0; i < n; ++i) {
cout << c[i].id << endl;
}
}
057 mysort
#include <iostream>
using namespace std;
struct A {
int nouse1;
int nouse2;
int n;
};
void mysort(void* a, int num, int width, int (*f)(const void* e1, const void* e2)){
char* c = (char*)a;//形参的名字可以跟实参相同,且此时在函数内部改变形参,实参不会发生改变
for (int i = 0; i < num - 1; ++i) {
for (int j = i + 1; j < num; ++j) {
//如果在位更大
char* p1 =(char*) c + width * i;//数组在传参的时候是例外,所以对c排序,最后输出a也是排序后的
char* p2 =(char*) c + width * j;
if (f(p1, p2) > 0) {
//冒泡排序是对每个(i)位置找最小,传统选择排序是找j位置的最小
for (int k = 0; k < width; k++) {
char tem = p1[k];//这个char换成int也行
p1[k] = p2[k];
p2[k] = tem;
}
}
}
}
}
int MyCompare1( const void * e1,const void * e2)
{
int * p1 = (int * ) e1;
int * p2 = (int * ) e2;
return * p1 - * p2;
}
int MyCompare2( const void * e1,const void * e2)
{
int * p1 = (int * ) e1;
int * p2 = (int * ) e2;
if( (* p1 %10) - (* p2 % 10))
return (* p1 %10) - (* p2 % 10);
else
return * p1 - * p2;
}
int MyCompare3( const void * e1,const void * e2)
{
A * p1 = (A*) e1;
A * p2 = (A*) e2;
return p1->n - p2->n;
}
int a[20];
A b[20];
int main ()
{
int n;
while(cin >> n) {
for(int i = 0;i < n; ++i) {
cin >> a[i];
b[i].n = a[i];
}
mysort(a,n,sizeof(int),MyCompare1);
for(int i = 0;i < n; ++i)
cout << a[i] << "," ;
cout << endl;
mysort(a,n,sizeof(int),MyCompare2);
for(int i = 0;i < n; ++i)
cout << a[i] << "," ;
cout << endl;
mysort(b,n,sizeof(A),MyCompare3);
for(int i = 0;i < n; ++i)
cout << b[i].n << "," ;
cout << endl;
}
return 0;
}
058 从字符串中取数
#include <iostream>
#include <iomanip>
using namespace std;
double GetDoubleFromString(char * str)
{
static char* start;
if(str){
start=str;
}
//跳过非数字
while(*start&&(*start<'0'||*start>'9')){
++start;
}
if(*start==0){
return NULL;
}
//遇到数字
double numble=0;
while(*start&&(*start>='0'&&*start<='9')){
numble=numble*10+(*start-'0');
++start;
}
//遇到小数点
double i=10;
if(*start=='.'){//注意此时不能写while,低级的错误
++start;
while(*start&&(*start>='0'&&*start<='9')){//其实*start可以不用写了
numble=numble+(*start-'0')/i;
++start;
i*=10;
}
}
return numble;
}
int main()
{
char line[300];
while(cin.getline(line,280)) {
double n;
n = GetDoubleFromString(line);
while( n > 0) {
cout << fixed << setprecision(6) << n << endl;
n = GetDoubleFromString(NULL);
}
}
return 0;
}
059 sort简单题
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[8] = {6,5,14,23,2,9,87,10 };
sort(
a+1,a+7,greater<int>()
);
for(int i = 0;i < 8; ++i)
cout << a[i] << "," ;
return 0;
}
060 还是sort简单题
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct Point{
int x;
int y;
};
struct Rule1
{
bool operator()(const int& a1, const int& a2) const {
if (a1 % 10 != a2 % 10) {
return a1 % 10 < a2 % 10;
}
else {
return a1 > a2;
}
}
};
struct Rule2
{
bool operator()(const Point& a1, const Point& a2) const {
int l1 = a1.x * a1.x + a1.y * a1.y;
int l2 = a2.x * a2.x + a2.y * a2.y;
if (l1 != l2) {
return l1 < l2;
}
else {
if (a1.x != a2.x)
return a1.x < a2.x;
else
return a1.y < a2.y;
}
}
};
int main()
{
int a[8] = {6,5,55,23,3,9,87,10 };
sort(a,a+8,Rule1());
for(int i = 0;i < 8; ++i)
cout << a[i] << "," ;
cout << endl;
Point ps[8] = {{1,0},{0,1},{0,-1},{-1,0},{1,-1},{1,1},{2,0},{-2,0} } ;
sort(ps,ps+8,Rule2());
for(int i = 0;i < 8; ++i)
cout << "(" << ps[i].x << "," << ps[i].y << ")";
return 0;
}
061 Set
#include<iostream>
#include<string>
#include<set>
#include<iterator>
using namespace std;
int main(){
multiset<int> mset;
set<int> sset;
char command[5];
int n,num;
multiset<int>::iterator it;
cin>>n;
for(int i=0;i<n;++i){
cin>>command>>num;
switch(command[1]){
case 'd':
mset.insert(num);
sset.insert(num);
cout<<mset.count(num)<<endl;
break;
case 'e':
cout<<mset.count(num)<<endl;
mset.erase(num);
break;
case 's':
if(sset.find(num)==sset.end())
cout<<"0 0"<<endl;
else{
cout<<"1 ";
cout<<mset.count(num)<<endl;
}
break;
}
}
return 0;
}
062 热血格斗场
#include<iostream>
#include<set>
#include<map>
#include<iterator>
using namespace std;
struct Member{
int zhanli;
int id;
}member;
typedef map<int,int> MP;//保证两人的战力不同
int main(){
MP mp;
int n;
//添加facer
member.id=1;
member.zhanli=1000000000;
mp.insert(make_pair(member.zhanli,member.id));
cin>>n;
while(n--){
cin>>member.id>>member.zhanli;
//先在现有map里找一个插入点,在一般情况下lower_bound找到的指针指向插入点+1位置
MP::iterator di=mp.lower_bound(member.zhanli);
MP::iterator gao;
//一般情况,即是在map中间插入
if(di!=mp.begin()){//如果不是最弱的
if(di!=mp.end()){//如果不是最强的
gao=di;
--di;//此时gao是比插入位置相邻强一位,di是比插入位置相邻弱一位
//讨论前后差距,如果前面差距小
if(member.zhanli-di->first>gao->first-member.zhanli){
cout<<member.id<<" "<<gao->second<<endl;
}
//讨论前后差距,如果后面差距小
else if(member.zhanli-di->first<gao->first-member.zhanli){
cout<<member.id<<" "<<di->second<<endl;
}
//讨论前后差距,如果前后一样
else if(member.zhanli-di->first==gao->first-member.zhanli){
cout<<member.id<<" "<<di->second<<endl;
}
}
else{//如果是最强的
--di;//因为end()返回值指向最后一个元素后面的迭代器
cout<<member.id<<" "<<di->second<<endl;
}
}
else{//如果是最弱的
cout<<member.id<<" "<<di->second<<endl;
}
//插入新的member
mp.insert(make_pair(member.zhanli,member.id));
}
return 0;
}
063 冷血格斗场
维护了一个有序队列,用multimap反而麻烦了。
#include<iostream>
#include<set>
#include<map>
#include<iterator>
using namespace std;
struct Member{
int zhanli;
int id;
}member;
typedef map<int,int> MP;//两人的实力值可以相同
int main(){
MP mp;//map<int, int> mp;其实不依赖struct,可以没有struct
int n;
//添加facer
mp[1000000000] = 1;//也可以写作(1)mp.insert(pair<int, int>(10...,1));(2) mp[1000000000] = 1;仅map可以用
cin>>n;
while(n--){
cin>>member.id>>member.zhanli;
//先在现有map里找一个插入点,在一般情况下lower_bound找到的指针指向插入点+1位置
MP::iterator di=mp.lower_bound(member.zhanli);//另一种写法auto it = mp.lower_bound(value); // 返回最小的大于等于value的迭代器
MP::iterator gao;
//一般情况,即是在map中间插入
if(di!=mp.begin()){//如果不是最弱的
if(di!=mp.end()){//如果不是最强的
gao=di;
--di;//此时gao是比插入位置相邻强一位,di是比插入位置相邻弱一位
//以下每种情况都要讨论 如果有多个人的实力值与他差别相同,则他会选择id最小的那个。
//讨论前后差距,如果前面差距小
if(member.zhanli-di->first>gao->first-member.zhanli){
cout<<member.id<<" "<<gao->second<<endl;
}
//讨论前后差距,如果后面差距小
else if(member.zhanli-di->first<gao->first-member.zhanli){
cout<<member.id<<" "<<di->second<<endl;
}
//讨论前后差距,如果前后一样
else if(member.zhanli-di->first==gao->first-member.zhanli){
if(gao->second<di->second)
cout<<member.id<<" "<<gao->second<<endl;
else
cout<<member.id<<" "<<di->second<<endl;
}
}
else{//如果是最强的
--di;//因为end()返回值指向最后一个元素后面的迭代器
cout<<member.id<<" "<<di->second<<endl;
}
}
else{//如果是最弱的
cout<<member.id<<" "<<di->second<<endl;
}
//插入新的member,这样的操作维护了一个有序队列,始终让某个战力值的位置是id最小的人等待被挑战(其他人不可能在后续被挑战),所以可以用map,这是本题的核心
di=mp.find(member.zhanli);
if(di==mp.end()||di->second>member.id)
mp[member.zhanli]=member.id;
}
return 0;
}
结语
终于把C++的OpenJudge题目做完了上传上来了,这63个题目很有意思,本文可供参考。