AcWing-语法基础课

入门第一个程序

  • 编程是一种控制计算机的方式,和我们平时双击打开文件、关机、重启没有任何区别
// 头文件区
#include <cstdio>
#include <iostream>

// 使用了std的命名空间
using namespace std;

// main函数
int main()
{
	// std::cout << "Hello World!" << endl;// 这一行也可以表示使用了std的命名空间

	cout << "Hello World!" << endl;

	return 0;// 返回0表示程序正常结束
}

变量

#include <iostream>

using namespace std;

int main()
{
	// 以下都是基于C++的常用的类型,整型、浮点型都是有符号的数
	// 布尔型,1Byte
	bool _a = true, _b = false;
	// 字符型,1Byte
	char a = 'c', b = 'a', c = ' ', d = '\n';
	// int型,4Byte
	int e, f = 1;
	// long long型,8Byte
	long long _ll = 1231231000000000000LL;// 如果不加LL的话这个数实际为int类型的整数

	// float型,4Byte
	float g = 1.5, h = 1, i = 1.235e2;// 整数是特殊浮点数
	// double型,8Byte
	// long double型,至少8Byte,不同的编译器这个字节数可能不同
	long double _ld = 12312312.12312;


	return 0;
}

输入输出

  • 学习语言最好的方式就是实践,每当掌握一个新功能时,就要立即将这个功能应用到实践中
#include <iostream>

using namespace std;
 
int main()
{
	int a, b;
	cin >> a >> b;// 输入两个变量的值
	cout << a + b << endl;// 输出两个变量相加的值。endl是回车的意思

}
#include <iostream>

using namespace std;
 
int main()
{
	int a, b;
	cin >> a;
	cin >> b;

	cout << a + b << ' ' << a * b << endl;

}
#include <cstdio>

int main()
{
	int a, b;

	scanf_s("%d,%d", &a, &b);

	printf("%d %d", a + b, a * b);

}
#include <cstdio>

int main()
{
	float a, b;

	scanf_s("%f,%f", &a, &b);

	printf("%.2f %.3f", a + b, a * b);// .2表示保留两位小数,.3表示保留三位小数

}
#include <cstdio>

int main()
{
	double a, b;

	scanf_s("%lf,%lf", &a, &b);

	printf("%lf %lf", a + b, a * b);

}
#include <cstdio>

int main()
{
	long long a, b;

	scanf_s("%lld,%lld", &a, &b);

	printf("%lld %lld", a + b, a * b);

}
  • cin和cout 与 scanf和printf的区别
    • scanf和printf 一定能够代替 cin和cout,反之则不行
    • cin在输入时能够帮我们过滤空格,scanf则不行,它会读入空格
    • scanf和printf 效率比 cin和cout高

运算

#include <iostream>

using namespace std;

int main()
{
	cout << 5 / 2 << endl;// 结果为2
	cout << 5.0 / 2.0 << endl;// 结果为2.5

	cout << 5 % 2 << endl;// 结果为1
	cout << 5 % -2 << endl;// 结果为1
	cout << -5 % 2 << endl;// 结果为-1,取模运算中结果的正负取决于被除数
}
#include <iostream>

using namespace std;

int main()
{
	int a = 6 + 3 * 4 / 2 - 2;
	cout << a << endl;
	
	int b = a * 10 + 5 / 2;
	cout << b << endl;

	cout << 23 * 56 - 78 / 3 << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a = 6;
	int j = a++;
	cout << a << ' ' << j << endl;

	int b = 6;
	int k = ++b;
	cout << b << ' ' << k << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a = 6;
	int b = 7;

	b += a;
	cout << b << endl;

	b -= a;
	cout << b << endl;

	b *= a;
	cout << b << endl;

	b /= a;
	cout << b << endl;

	b %= a;
	cout << b << endl;

	return 0;
}

不同类型的变量相互赋值

#include <iostream>

using namespace std;

int main()
{
	int a = 5;
	float b = (float)a;
	
	float _a = 5.23;
	int _b = (int)_a;
	
	int t = 97;
	char _t = (char)t;

	char c = 'A';

	cout << b << endl;

	cout << _b << endl;

	cout << _t << endl;

	cout << (char)(c + 33) << endl;

	return 0;
}

类型的隐形转换

  • 精度低和精度高的不同类型的两个数作运算,结果会默认转为精度高的类型的数
#include <iostream>

using namespace std;

int main()
{
	int a = 6;
	float b = 1.3;

	cout << a * b << endl;// 结果为7.8

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	char x = 'A';
	cout << (char)(x + 2) << endl;

	return 0;
}

所有C的文件都能被C++编译,反之则不一定。

习题

A+B

#include <iostream>
#include <bits/stdc++.h> //这是万能头文件

using namespace std;
 
int main()
{
	int a, b;
	cin >> a >> b;// 输入两个变量的值
	cout << a + b << endl;// 输出两个变量相加的值。endl是回车的意思

    return 0;
}

#include <iostream>

using namespace std;

int main()
{
	int A, B, C, D;

	cin >> A >> B >> C >> D;

	cout << "DIFERENCA = " << (A * B - C * D) << endl;

	return 0;
}

圆的面积

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double R;// 在算法题中,一般用double来定义浮点数,因为double的有效数比较长

	cin >> R;

	printf("A=%.4lf", 3.14159 * R * R);

	return 0;
}

平均数1

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a, b;

	cin >> a >> b;
	
	printf("MEDIA = %.5lf", (a * 3.5 + b * 7.5) / 11);

	return 0;
}

工资

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int number, time;
	double salary;

	cin >> number >> time >> salary;

	cout << "NUMBER = " << number << endl;
	printf("SALARY = U$ %.2lf", time * salary);

	return 0;
}

油耗

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int distance;
	double oil;

	cin >> distance >> oil;
	
	printf("%.3lf km/l", distance / oil);

	return 0;
}

两点间的距离

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int main()
{
	double x1, y1;
	double x2, y2;

	cin >> x1 >> y1;
	cin >> x2 >> y2;

	printf("%.4lf", sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));

	return 0;
}

钞票

#include <iostream>

using namespace std;

int main()
{
	int n;

	cin >> n;

    cout << n << endl;
	cout << n / 100 << " nota(s) de R$ 100,00" << endl;
	n %= 100;
	cout << n / 50 << " nota(s) de R$ 50,00" << endl;
	n %= 50;
	cout << n / 20 << " nota(s) de R$ 20,00" << endl;
	n %= 20;
	cout << n / 10 << " nota(s) de R$ 10,00" << endl;
	n %= 10;
	cout << n / 5 << " nota(s) de R$ 5,00" << endl;
	n %= 5;
	cout << n / 2 << " nota(s) de R$ 2,00" << endl;
	n %= 2;
	cout << n / 1 << " nota(s) de R$ 1,00" << endl;

	return 0;
}

时间转换

#include <iostream>

using namespace std;

int main()
{
	int time;

	cin >> time;

	cout << time / 3600 << ":" << time % 3600 / 60 << ":" << time % 3600 % 60 / 1;

	return 0;
}

简单乘积

#include <iostream>

using namespace std;

int main()
{
	int a, b;
	int PROD;

	cin >> a >> b;

	PROD = a * b;

	cout << "PROD = " << PROD;

	return 0;
}

简单计算

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int id1, number1;
	double price1;
	int id2, number2;
	double price2;

	cin >> id1 >> number1 >> price1;
	cin >> id2 >> number2 >> price2;

	printf("VALOR A PAGAR: R$ %.2lf", (number1 * price1) + (number2 * price2));

	return 0;
}

球的体积

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int R;
	double PI = 3.14159;

	cin >> R;

	printf("VOLUME = %.3lf", (4 / 3.0) * PI * R * R * R);

	return 0;
}

面积

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double A, B, C;

	cin >> A >> B >> C;

	printf("TRIANGULO: %.3lf\n", A * C / 2);
	printf("CIRCULO: %.3lf\n", 3.14159 * C * C);
	printf("TRAPEZIO: %.3lf\n", (A + B) * C / 2);
	printf("QUADRADO: %.3lf\n", B * B);
	printf("RETANGULO: %.3lf\n", A * B);

	return 0;
}

平均数2

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a, b, c;

	cin >> a >> b >> c;
	printf("MEDIA = %.1lf", (a * 2 + b * 3 + c * 5) / 10);

	return 0;
}

工资和奖金

#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main()
{
	string name;
	cin >> name;

	double x, y;

	cin >> x >> y;
	
	printf("TOTAL = R$ %.2lf", x + y * 0.15);

	return 0;
}

最大值

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int a, b, c;
	int temp;

	cin >> a >> b >> c;
	
    // 长度为a的线段,长度为b的线段,长度为a和b作差的绝对值的线段。这三个长度的线段相加除以2,得到的结果即最长的线段的值
	temp = (a + b + abs(a - b)) / 2;

	cout << (temp + c + abs(temp - c)) / 2 << " eh o maior";

	return 0;
}

距离

#include <iostream>

using namespace std;

int main()
{
	int L;

	cin >> L;
	cout << 2 * L << " minutos" << endl;

	return 0;
}

燃料消耗

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int v, t;
	double oil;
	double use = 12;

	cin >> t >> v;

	oil = t * v / use;

	printf("%.3lf", oil);

	return 0;
}

钞票和硬币

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double value;

	cin >> value;

	int _integer;
	int _decimal;
	int _temp;

	_temp = value * 100;

	_integer = value - _temp % 100 / 100;
	_decimal = _temp % 100;

	cout << "NOTAS:" << endl;
	cout << _integer / 100 << " nota(s) de R$ 100.00" << endl;
	cout << _integer % 100 / 50 << " nota(s) de R$ 50.00" << endl;
	cout << _integer % 100 % 50 / 20 << " nota(s) de R$ 20.00" << endl;
	cout << _integer % 100 % 50 % 20 / 10 << " nota(s) de R$ 10.00" << endl;
	cout << _integer % 100 % 50 % 20 % 10 / 5 << " nota(s) de R$ 5.00" << endl;
	cout << _integer % 100 % 50 % 20 % 10 % 5 / 2 << " nota(s) de R$ 2.00" << endl;

	cout << "MOEDAS:" << endl;
	cout << _integer % 100 % 50 % 20 % 10 % 5 % 2 / 1 << " moeda(s) de R$ 1.00" << endl;
	cout << _decimal / 50 << " moeda(s) de R$ 0.50" << endl;
	cout << _decimal % 50 / 25 << " moeda(s) de R$ 0.25" << endl;
	cout << _decimal % 50 % 25 / 10 << " moeda(s) de R$ 0.10" << endl;
	cout << _decimal % 50 % 25 % 10 / 5 << " moeda(s) de R$ 0.05" << endl;
	cout << _decimal % 50 % 25 % 10 % 5 / 1 << " moeda(s) de R$ 0.01" << endl;

	return 0;
}

天数转换

#include <iostream>

using namespace std;

int main()
{
	int days;

	cin >> days;

	cout << days / 365 << " ano(s)" << endl;
	cout << days % 365 / 30 << " mes(es)" << endl;
	cout << days % 365 % 30 / 1 << " dia(s)" << endl;

	return 0;
}

printf的固定宽度的输出

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a = 1;
	int b = 23;
	int c = 456;

	printf("%5d!\n", a);// 表示占用5个长度,如果不足5位则在数字的左边补上空格
	printf("%5d!\n", b);
	printf("%5d!\n", c);

	printf("%-5d!\n", a);// 表示占用5个长度,如果不足5位则在数字的右边补上空格
	printf("%-5d!\n", b);
	printf("%-5d!\n", c);

	printf("%05d!\n", a);// 表示占用5个长度,如果不足5位则在数字的左边补上0
	printf("%05d!\n", b);
	printf("%05d!\n", c);

	return 0;
}

if-else

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int score;

	cin >> score;

	if (score >= 60)
	{
		cout << "及格!" << endl;
		cout << "你真棒!" << endl;
	}
	else
	{
		cout << "不及格!" << endl;
		cout << "再接再厉!" << endl;
	}

	cout << "结束!";

	return 0;
}
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int x;

	cin >> x;

	if (x >= 0)
	{
		cout << x << endl;
	}
	else
	{
		cout << -x << endl;
	}

	return 0;
}
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a, b;

	cin >> a >> b;

	if (a > b) cout << a << endl;
	else cout << b << endl;

	return 0;
}
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int grade;

	cin >> grade;

	if (grade >= 85) cout << 'A' << endl;
	else if (grade >= 70) cout << 'B' << endl;
	else if (grade >= 60) cout << 'C' << endl;
	else cout << 'D' << endl;

	return 0;
}
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a, b;
	char c;

	cin >> a >> b >> c;

	if (c == '+') cout << a + b << endl;
	else if (c == '-') cout << a - b << endl;
	else if (c == '*') cout << a * b << endl;
	else if (c == '/')
	{
		if (b == 0) cout << "Divided by zero!" << endl;
		else cout << a / b << endl;
	}
	else cout << "Invalid operator!" << endl;

	return 0;
}
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int year;
	
	cin >> year;

	if (!(year % 400) || (year % 100 && !(year % 4)))
		cout << year << "是闰年!" << endl;
	else cout << year << "不是闰年!" << endl;

	return 0;
}

习题

倍数

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a, b;

	cin >> a >> b;

	if (a % b == 0 || b % a == 0)
		cout << "Sao Multiplos" << endl;
	else cout << "Nao sao Multiplos" << endl;

	return 0;
}

零食

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int x, y;

	cin >> x >> y;

	if (x == 1) printf("Total: R$ %.2lf", y * 4.00);
	if (x == 2) printf("Total: R$ %.2lf", y * 4.50);
	if (x == 3) printf("Total: R$ %.2lf", y * 5.00);
	if (x == 4) printf("Total: R$ %.2lf", y * 2.00);
	if (x == 5) printf("Total: R$ %.2lf", y * 1.50);

	return 0;
}

区间

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double x;

	cin >> x;

    if (x >= 0 && x <= 25) cout << "Intervalo [0,25]" << endl;
	else if (x > 25 && x <= 50) cout << "Intervalo (25,50]" << endl;
	else if (x > 50 && x <= 75) cout << "Intervalo (50,75]" << endl;
	else if (x > 75 && x <= 100) cout << "Intervalo (75,100]" << endl;
	else cout << "Fora de intervalo" << endl;

	return 0;
}

三角形

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a, b, c;

	cin >> a >> b >> c;

	if ((a + b > c) && (a + c > b) && (b + c > a))
		printf("Perimetro = %.1lf", a + b + c);
	else printf("Area = %.1lf", (a + b) * c / 2);

	return 0;
}

游戏时间

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a, b;

	cin >> a >> b;

	if (b > a)
		cout << "O JOGO DUROU " << b - a << " HORA(S)";
	if (b < a)
		cout << "O JOGO DUROU " << 24 - (a - b) << " HORA(S)";
	if (a == b)
		cout << "O JOGO DUROU " << 24 << " HORA(S)";
	
	return 0;
}

加薪

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double salary, perc, _newSalary, _upSalary;
	
	cin >> salary;

	if (salary >= 0 && salary <= 400.00) perc = 0.15;
	if (salary >= 400.01 && salary <= 800.00) perc = 0.12;
	if (salary >= 800.01 && salary <= 1200.00) perc = 0.10;
	if (salary >= 1200.01 && salary <= 2000.00) perc = 0.07;
	if (salary > 2000.00 && salary <= 2500.00) perc = 0.04;

	_newSalary = salary + salary * perc;

	_upSalary = _newSalary - salary;

	printf("Novo salario: %.2lf\n", _newSalary);
	printf("Reajuste ganho: %.2lf\n", _upSalary);
	printf("Em percentual: %.0lf %\n", perc * 100);

	return 0;
}

动物

#include <iostream>

using namespace std;

int main()
{
	string a, b, c, animal;

	cin >> a >> b >> c;

	if (a == "vertebrado")
	{
		if (b == "ave")
		{
			if (c == "carnivoro")
				animal = "aguia";
			else
				animal = "pomba";
		}
		else
		{
			if (c == "onivoro")
				animal = "homem";
			else
				animal = "vaca";
		}
	}
	else
	{
		if (b == "inseto")
		{
			if (c == "hematofago")
				animal = "pulga";
			else
				animal = "lagarta";
		}
		else
		{
			if (c == "hematofago")
				animal = "sanguessuga";
			else
				animal = "minhoca";
		}
	}

	cout << animal << endl;

	return 0;
}

选择练习1

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a, b, c, d;

	cin >> a >> b >> c >> d;

	if (b > c && d > a && c + d > a + b && c > 0 && d > 0 && a % 2 == 0)
		cout << "Valores aceitos" << endl;
	else cout << "Valores nao aceitos" << endl;

	return 0;
}

DDD

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int cityNumber;

	cin >> cityNumber;

	if (cityNumber == 61) cout << "Brasilia" << endl;
	else if (cityNumber == 71) cout << "Salvador" << endl;
	else if (cityNumber == 11) cout << "Sao Paulo" << endl;
	else if (cityNumber == 21) cout << "Rio de Janeiro" << endl;
	else if (cityNumber == 32) cout << "Juiz de Fora" << endl;
	else if (cityNumber == 19) cout << "Campinas" << endl;
	else if (cityNumber == 27) cout << "Vitoria" << endl;
	else if (cityNumber == 31) cout << "Belo Horizonte" << endl;
	else cout << "DDD nao cadastrado" << endl;

	return 0;
}

点的坐标

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double a, b;

	cin >> a >> b;

	if (a == 0 && b == 0) cout << "Origem" << endl;
	else if (a == 0) cout << "Eixo Y" << endl;
	else if (b == 0) cout << "Eixo X" << endl;

	if (a > 0)
	{
		if (b > 0) cout << "Q1" << endl;
		if (b < 0) cout << "Q4" << endl;
	}
	if (a < 0)
	{
		if (b > 0) cout << "Q2" << endl;
		if (b < 0) cout << "Q3" << endl;
	}
	return 0;
}

三角形类型

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double a, b, c, max, mid, min;

	cin >> a >> b >> c;

	if (a >= b)
	{
		if (a >= c)
		{
			max = a;
			if (b >= c)
			{
				mid = b;
				min = c;
			}
			else
			{
				mid = c;
				min = b;
			}
		}
		else
		{
			max = c;
			mid = a;
			min = b;
		}
	}
	else
	{
		if (a >= c)
		{
			max = b;
			mid = a;
			min = c;
		}
		else
		{
			if (b >= c)
			{
				max = b;
				mid = c;
				min = a;
			}
			else
			{
				max = c;
				mid = b;
				min = a;
			}
		}
	}

	if (max >= mid + min) cout << "NAO FORMA TRIANGULO" << endl;
	else
	{
		if (max * max == mid * mid + min * min) cout << "TRIANGULO RETANGULO" << endl;
		if (max * max > mid * mid + min * min) cout << "TRIANGULO OBTUSANGULO" << endl;
		if (max * max < mid * mid + min * min) cout << "TRIANGULO ACUTANGULO" << endl;
		if (max == mid && mid == min && max == min) cout << "TRIANGULO EQUILATERO" << endl;
		if (max == mid && mid != min || max != mid && mid == min) cout << "TRIANGULO ISOSCELES" << endl;
	}

	return 0;
}

游戏时间2

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int ah, am, ch, cm, hour, minute;

	cin >> ah >> am >> ch >> cm;

	if (ah > ch)
	{
		hour = 24 - (ah - ch);
		if (am > cm)
		{
			minute = 60 - (am - cm);
			hour = hour - 1;
		}
		else
		{
			minute = cm - am;
		}
	}
	else if (ah < ch)
	{
		hour = ch - ah;
		if (am > cm)
		{
			minute = 60 - (am - cm);
			hour = hour - 1;
		}
		else
		{
			minute = cm - am;
		}
	}
	else
	{
		if (am > cm)
		{
			minute = 60 - (am - cm);
			hour = 23;
		}
		else if (am < cm)
		{
			minute = cm - am;
			hour = 0;
		}
		else
		{
			minute = 0;
			hour = 24;
		}
	}

	cout << "O JOGO DUROU " << hour << " HORA(S) E " << minute << " MINUTO(S)" << endl;

	return 0;
}

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double salary, iit;

	cin >> salary;

	if (salary >= 0.00 && salary <= 2000.00)
		cout << "Isento" << endl;
	else
	{
		if (salary >= 2000.01 && salary <= 3000.00)
		{
			iit = (salary - 2000.00) * 0.08;
		}
		if (salary >= 3000.01 && salary <= 4500.00)
		{
			iit = 1000 * 0.08 + (salary - 3000.00) * 0.18;
		}
		if (salary > 4500.00)
		{
			iit = 1000 * 0.08 + 1500 * 0.18 + (salary - 4500.00) * 0.28;
		}

		printf("R$ %.2lf", iit);
	}

	return 0;
}

简单排序

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int a, b, c, max, mid, min;

	cin >> a >> b >> c;

	if (a >= b)
	{
		if (a >= c)
		{
			max = a;
			if (b >= c)
			{
				mid = b;
				min = c;
			}
			else
			{
				mid = c;
				min = b;
			}
		}
		else
		{
			max = c;
			mid = a;
			min = b;
		}
	}
	else
	{
		if (b <= c)
		{
			max = c;
			mid = b;
			min = a;
		}
		else
		{
			if (a >= c)
			{
				max = b;
				mid = a;
				min = c;
			}
			else
			{
				max = b;
				mid = c;
				min = a;
			}
		}
	}

	cout << min << endl << mid << endl << max << endl;
	cout << endl;
	cout << a << endl << b << endl << c << endl;

	return 0;
}

一元二次方程公式

#include <cstdio>
#include <iostream>
#include <cmath>

using namespace std;

int main()
{
	double a, b, c, x1, x2;

	cin >> a >> b >> c;

	if (b * b - 4 * a * c < 0 || a == 0)
		cout << "Impossivel calcular" << endl;
	else
	{
		x1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
		x2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);

		printf("R1 = %.5lf\n", x1);
		printf("R2 = %.5lf\n", x2);
	}

	return 0;
}

平均数3

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double a, b, c, d, y, media, z;

	cin >> a >> b >> c >> d;

	media = (a * 2 + b * 3 + c * 4 + d * 1) / 10;

	printf("Media: %.1lf\n", media);

	if (media >= 7.0)
		cout << "Aluno aprovado." << endl;
	else if (media < 5.0)
		cout << "Aluno reprovado." << endl;
	else
	{
		cout << "Aluno em exame." << endl;
		cin >> y;
		printf("Nota do exame: %.1lf\n", y);
		z = (media + y) / 2;
		if (z >= 5.0)
			cout << "Aluno aprovado." << endl;
		else
			cout << "Aluno reprovado." << endl;
		printf("Media final: %.1lf", z);
	}

	return 0;
}

循环

  • 学习编程语言语法是次要的,思维是主要的。如何把头脑中的想法变成简洁的代码,至关重要
#include <iostream>

using namespace std;

int main()
{
	int i = 1, num = 0;

	while (i <= 100)
	{
		num += i * i * i;

		i++;
	}

	cout << num << endl;

	return 0;
}

求斐波那契数列的第n项

已知:f(1)=1,f(2)=1,f(3)=2,f(n)=f(n-1)+f(n-2)

#include <iostream>

using namespace std;

int main()
{
	int a = 1, b = 1;
	int n;

	cin >> n;// n>=3

	int i = 0;

	while (i < n - 1) // i从0开始,循环n-1次
	{
		// 一定要知道循环哪个过程能找出f(n)的值
		// 这里没有用到递归
		int c = a + b;
		a = b;
		b = c;
		i++;
	}

	cout << a << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int sum = 0;

	for (int i = 1; i <= 100; i++)
	{
		sum += i * i * i;
	}

	cout << sum << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a, b;
	int n;

	a = 1;
	b = 1;

	cin >> n;

	for (int i = 0; i < n - 1; i++)
	{
		int c = a + b;
		a = b;
		b = c;
	}

	cout << a << endl;

	return 0;
	
}
#include <iostream>

using namespace std;

int main()
{
	int sum = 0;
	
	for (int i = 1, j = 10; i < j; i++, j--)// for循环比较灵活
	{
		sum += i * j;
	}

	cout << sum << endl;

	return 0;
}
  • 如果是多层循环的话,使用break只能跳出一层循环

  • continue跳出当前循环,进入下一次循环

#include <iostream>

using namespace std;

int main()
{
	int n, p = 1;

	cin >> n;

	for (int i = 2; i < n; i++)
	{
		if (n % i == 0)
		{
			cout << n << " 不是质数";
			p = 0;
			break;
		}
	}
	if (p == 1)
		cout << n << " 是质数";

	return 0;	
}
#include <iostream>

using namespace std;

int main()
{
	int n, sum = 0;

	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		if (i % 2)
			continue;
		sum += i;
	}

	cout << sum << endl;

	return 0;
}
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	int n, sum = 0;

	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			sum++;
			printf("%-5d", sum);				
		}
		cout << endl;
	}
    
    return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int n, f = 1;

	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		for (int j = 2; j <= i - 1; j++)
		{
			if (i % j == 0)
			{
				f = 0;
				break;
			}
		}
		if (f)
			cout << "质数:" << i << endl;
		f = 1;
	}

	return 0;
}

曼哈顿距离:已知两个点的坐标 (x1,y1) (x2,y2) 则曼哈顿距离为 |x1-x2|+|y1-y2|

#include <iostream>

using namespace std;

int main()
{
	int n;

	cin >> n;// 输入的n为奇数

	int cx = n / 2, cy = n / 2;

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (abs(i - cx) + abs(j - cy) <= n / 2)
				cout << '*';
			else
				cout << ' ';
		}
		cout << endl;
	}
    
    return 0;
}

习题

偶数

#include <iostream>

using namespace std;

int main()
{
	for (int i = 2; i <= 100; i += 2)
	{
		cout << i << endl;
	}

	return 0;
}

奇数

#include <iostream>

using namespace std;

int main()
{
	int x;

	cin >> x;

	for (int i = 1; i <= x; i++)
	{
		if (i % 2 == 0)
			continue;
		cout << i << endl;
	}

	return 0;
}

正数

#include <iostream>

using namespace std;

int main()
{
	double a;
	int num = 0;

	for (int i = 1; i <= 6; i++)
	{
		cin >> a;
		if (a > 0)
			num++;
	}

	cout << num << " positive numbers" << endl;

	return 0;
}

连续奇数的和 1

#include <iostream>

using namespace std;

int main()
{
	int x, y, temp;
	int num = 0;

	cin >> x >> y;

	if (x > y)
	{
		temp = x;
		x = y;
		y = temp;
	}

	for (int i = x + 1; i < y; i++)
	{
		if (i % 2 == 0)
			continue;
		num += i;
	}
	
	cout << num << endl;

	return 0;
}

最大数和它的位置

#include <iostream>

using namespace std;

int main()
{
	int x;
	int max;
	int k;

	for (int i = 1; i <= 100; i++)
	{
		cin >> x;
		if (i == 1)
		{
			max = x;
			k = i;
			continue;
		}
		if (x > max)
		{
			max = x;
			k = i;
		}
	}

	cout << max << endl << k;
	
	return 0;
}

递增序列

#include <iostream>

using namespace std;

int main()
{
	int x = 1;
	int k = 0;
	int flag = 1;

	// cin本身是有返回值的,如果返回值是0表示没有读到值,表示读到了文件的结束符。
	while (cin >> x && x)// 这里的意思是:判断cin有没有读到值,并且判断读到的值为x
	{
		for (int i = 1; i <= x; i++)
		{
			cout << i << ' ';
		}
		cout << endl;
	}

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int x = 1;
	int k = 0;
	int flag = 1;

	while (cin >> x, x)// 也可以这么写,这个叫逗号表达式。逗号表达式的真假只等于最后一个数的真假。
	{
		for (int i = 1; i <= x; i++)
		{
			cout << i << ' ';
		}
		cout << endl;
	}

	return 0;
}

知识点补充

#include <iostream>

using namespace std;

int main()
{
	int x;
	int cnt = 0;

	while (cin >> x && x) 
		cnt++;// 这样可以统计输入了多少个非零的数
	cnt++;

	cout << cnt << endl;// 展示输出了多少次

	return 0;
}
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int x;
	int cnt = 0;
	
	// while (~scanf_s("%d", &x) && x) 这种写法等价于下面那一行的写法
	while (scanf_s("%d", &x) != -1 && x)// scanf返回-1表示没有读到值
		cnt++;// 这样可以统计输入了多少个非零的数
	cnt++;

	cout << cnt << endl;// 展示输出了多少次

	return 0;
}

连续整数相加

#include <iostream>

using namespace std;

int main()
{
	int a, x;
	int num = 0;

	cin >> a;

	while (cin >> x)
	{
		if (x > 0)
		{
			for (int i = a; i < a + x; i++)
			{
				num += i;
				
			}
			cout << num << endl;
			break;
		}
	}

	return 0;
}

约数

#include <iostream>

using namespace std;

int main()
{
	int x;

	cin >> x;

	for (int i = 1; i <= x; i++)
	{
		if (x % i == 0)
			cout << i << endl;
	}

	return 0;
}

PUM

#include <iostream>

using namespace std;

int main()
{
	int x, y;
	int num = 0;

	cin >> x >> y;

	for (int i = 1; i <= x; i++)
	{
		for (int j = 1; j <= y; j++)
		{
			num++;
			if (j == y)
			{
				cout << "PUM";
				break;
			}
			cout << num << " ";
		}
		cout << endl;
	}

	return 0;
}

余数

#include <iostream>

using namespace std;

int main()
{
	int x;

	cin >> x;

	for (int i = 2; i < 10000; i++)
	{
		if (i % x == 2)
			cout << i << endl;
	}

	return 0;
}

六个奇数

#include <iostream>

using namespace std;

int main()
{
	int x;
	int num = 6;
	bool flag = true; 	

	cin >> x;

	if (x % 2)
	{
		num--;
		cout << x << endl;
	}
	else
	{
		x++;
		num--;
		cout << x << endl;
	}

	for (int i = 1; i <= num; i++)
	{
		x += 2;
		cout << x << endl;
	}

	return 0;
}

乘法表

#include <iostream>

using namespace std;

int main()
{
	int n;

	cin >> n;

	for (int i = 1; i <= 10; i++)
	{
		cout << i << " x " << n << " = " << i * n << endl;
	}

	return 0;
}

实验

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double x, cx = 0, rx = 0, fx = 0, totalAnimal;
	double y;
	char c;

	cin >> x;

	for (int i = 1; i <= x; i++)
	{
		cin >> y >> c;
		if (c == 'C')
			cx += y;
		if (c == 'R')
			rx += y;
		if (c == 'F')
			fx += y;
	}
	
	totalAnimal = cx + rx + fx;

	printf("Total: %.0lf animals\n", totalAnimal);
	printf("Total coneys: %.0lf\n", cx);
	printf("Total rats: %.0lf\n", rx);
	printf("Total frogs: %.0lf\n", fx);
	printf("Percentage of coneys: %.2lf %\n", cx / totalAnimal * 100);
	printf("Percentage of rats: %.2lf %\n", rx / totalAnimal * 100);
	printf("Percentage of frogs: %.2lf %\n", fx / totalAnimal * 100);

	return 0;

}

区间 2

#include <iostream>

using namespace std;

int main()
{
	int n, x, xIn = 0, xOut = 0;

	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		cin >> x;
		if (x <= 20 && x >= 10)
			xIn++;
		else
			xOut++;
	}

	cout << xIn << " in" << endl;
	cout << xOut << " out" << endl;

	return 0;
}

连续奇数的和 2

#include <iostream>

using namespace std;

int main()
{
	int n, x, y, sum = 0;

	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		cin >> x >> y;
		if (x >= y)
		{
			int temp = x;
			x = y;
			y = temp;
		}
		int d = y - x;
		for (int j = 1; j <= d - 1; j++)
		{
			x++;
			if (x % 2)
				sum += x;
		}
		cout << sum << endl;
		sum = 0;
	}

	return 0;
}

简单斐波那契

#include <iostream>

using namespace std;

int main()
{
	int a = 0, b = 1;
	int n;

	cin >> n;

	cout << 0 << " ";

	for (int i = 0; i < n - 1; i++)
	{
		int temp = a;
		a = b;
		b = temp + b;
		
		cout << a << " ";
	}

	return 0;

}

数字序列和它的和

#include <iostream>

using namespace std;

int main()
{
	int x, y;

	while (1)
	{
		int sum = 0;

		cin >> x;
		cin >> y;

		if (x <= 0 || y <= 0)
			break;

		if (x > y)
		{
			int temp = x;
			x = y;
			y = temp;
		}

		for (int i = x; i <= y; i++)
		{
			sum += i;
			cout << i << " ";
		}

		cout << "Sum=" << sum << endl;
	}

	return 0;
}

完全数

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
	int n;
	long long x;
	long long num = 0LL;

	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		cin >> x;
		for (long long j = 1; j < x / j; j++)// 这里找一个数的约数时,一定要进行优化,不然会超时!
		{
			if (x % j)
				continue;
			num = num + j + x / j;
		}
		num -= x;
		if (num == x)
			cout << x << " is perfect" << endl;
		else
			cout << x << " is not perfect" << endl;
		num = 0;
	}

	return 0;
}

质数

#include <iostream>

using namespace std;

int main()
{
	int n;

	cin >> n;

	while (n--)
	{
		int p;

		cin >> p;

		bool is_prime = true;

		for (int i = 2; i <= p / i; i++)
		{
			if (p % i == 0)
			{
				is_prime = false;
				break;
			}
		}

		if (is_prime)
			cout << p << " is prime" << endl;
		else
			cout << p << " is not prime" << endl;
	}

	return 0;
}

菱形

#include <iostream>

using namespace std;

int main()
{
	int cx, cy;
	int n;

	cin >> n;

	cx = n / 2;
	cy = n / 2;

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (abs(i - cx) + abs(j - cy) <= n / 2)
				cout << '*';
			else
				cout << ' ';
		}
		cout << endl;
	}

	return 0;
}

数组

  • 程序 = 逻辑 + 数据。数组是存储数据的强而有力的手段
#include <iostream>

using namespace std;

int main()
{
	int a[100], b[10];
	float c[11];
	double d[13];
	char e[14];
	string g[25];

	return 0;
}
#include <iostream>

using namespace std;

// 函数外面的变量(全局变量)会放到堆空间里面,并且数组中未赋值的数一定都是0。
// 这里的数组里面的值就不会是随机数。
int j[1000000];

// 局部变量会放到栈空间里面。

int main()
{
	int a[3] = { 0, 1, 3 };
	int b[] = { 0, 1, 1 };

	int c[5] = { 0, 1, 1 };// 数组长度为5,没有给出的值默认为0
	
	char d[] = { 'a', 'b', 'c' };

	int f[10] = { 0 };// 将数组全部初始化成0的写法
	int g[10];// 数组里面值为随机值
    
    int res[100][100] = { };// 局部变量中,将二维数组全部初始化为0的写法

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[3] = { 0, 1, 2 };

	cout << a[0] << ' ' << a[1] << ' ' << a[2] << endl;

	a[0] = 5;

	cout << a[0] << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int f[100];

	f[0] = 0;
	f[1] = 1;

	int n;

	cin >> n;

	for (int i = 2; i <= n; i++)
	{
		f[i] = f[i - 2] + f[i - 1];
	}

	cout << f[n] << endl;

	return 0; 
}
#include <iostream>

using namespace std;

int main()
{
	int f[100];

	int n;

	cin >> n;

	for (int i = 0; i < n; i++)
		cin >> f[i];
	for (int j = n - 1; j >= 0; j--)
		cout << f[j] << ' ';
	cout << endl;

	return 0;	
}
#include <iostream>

using namespace std;

int main()
{
	int a[100];

	int n, k;

	cin >> n >> k;

	for (int i = 0; i < n; i++)
		cin >> a[i];

	while (k--)
	{
		int temp = a[n - 1];
		for (int i = n - 2; i >= 0; i--)
		{
			a[i + 1] = a[i];
		}
		a[0] = temp;
	}

	for (int i = 0; i < n; i++)
	{
		cout << a[i] << ' ';
	}

	cout << endl;
	
	return 0;
}
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	int a[100];

	int n, k;

	cin >> n >> k;

	for (int i = 0; i < n; i++)
		cin >> a[i];

	// 反转的意思:1 2 3 4 5 -----反转后------> 5 4 3 2 1
	// 翻转的意思:1 2 3 4 5 ---顺时针翻转2次后---> 4 5 1 2 3

	// reverse是反转函数,第一个参数:要反转的起始位置,第二个参数:要反转的终止位置的下一个位置
	reverse(a, a + n);
	reverse(a, a + k);
	reverse(a + k, a + n);

	for (int i = 0; i < n; i++)
		cout << a[i] << ' ';
	cout << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[100];
	int n;

	cin >> n;

	for (int i = 0; i < n; i++)
		cin >> a[i];

	for (int i = 0; i < n; i++)
		for (int j = i + 1; j < n; j++)
			if (a[i] > a[j])
			{
				int temp = a[j];
				a[j] = a[i];
				a[i] = temp;
			}

	for (int i = 0; i < n; i++)
		cout << a[i] << endl;

	return 0;
}
// 实现高精度运算
#include <iostream>

using namespace std;

const int N = 3010;

int main()
{
	int a[N] = { 1 };
	int n;
	int m = 1;

	cin >> n;

	for (int i = 0; i < n; i++)
	{
		int t = 0;
		for (int j = 0; j < m; j++)
		{
			t += a[j] * 2;
			a[j] = t % 10;
			t /= 10;
		}
		if (t)
			a[m++] = t;
	}

	for (int i = m - 1; i >= 0; i--)
		cout << a[i];

	cout << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[3][4];

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			a[i][j] = i + j;
			cout << a[i][j] << ' ';
		}
		cout << endl;
	}

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[3] = { 0, 1, 2 };

	int b[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11} };

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			cout << b[i][j] << ' ';
		}
		cout << endl;
	}

	return 0;
}
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	int a[10], b[10];
	 
	// 初始化数组的常用函数:memset()
	/*
		第一个参数:从哪里开始。直接写数组的名字相当于从数组的初始位置开始
		第二个参数:把数组中的每一个字节的值赋值为多少
		第三个参数:初始化多长(长度单位为字节)
	*/
	memset(a, 1, 40);// 每个int占4个字节
	// 把数组中的每个字节赋值为1:0000 0001 0000 0001 0000 0001 0000 0001 
	// 对应的十进制数为:16843009

	for (int i = 0; i < 10; i++)
		cout << a[i] << ' ';
	cout << endl;

	// 把数组中的每个字节赋值为-1:1111 1111 1111 1111 1111 1111 1111 1111
	// memset(b, -1, 40);
	memset(b, -1, sizeof b);// sizeof b 直接求数组b的字节长度。也可以写成 sizeof(b)
	cout << sizeof b << endl;
	for (int i = 0; i < 10; i++)
		cout << b[i] << ' ';
	cout << endl;

	return 0;
}
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	int a[10], b[10];

	for (int i = 0; i < 10; i++)
		a[i] = i;
	
	// 复制数组的函数:memcpy() 
	/*
		第一个参数:目标数组
		第二个参数:原数组
		第三个参数:复制的长度(长度单位是字节)
	*/
	memcpy(b, a, sizeof a);

	for (int i = 0; i < 10; i++)
		cout << b[i] << ' ';
	cout << endl;

	return 0;
}

知识点补充

#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

const double eps = 1e-6;

double C(int a, int b)// 返回组合数的结果
{
	double res = 1;
	for (int i = 1, j = a; i <= b; i++, j--)
		res = res * j / i;
	return res;
}

int main()
{
	int a = 3;
	if (sqrt(3) * sqrt(3) < 3)
		cout << "!!!" << endl;
	if (fabs(sqrt(3) * sqrt(3) - 3) < eps)// fabs(x) 返回x的绝对值
		cout << "这两个数的差值,小于某个误差,我们就认为这两个数相等" << endl;

	cout << C(5, 2) << endl;

	return 0;
}

习题

数组替换

#include <iostream>

using namespace std;

int main()
{
	int a[100];

	for (int i = 0; i < 10; i++)
	{
		cin >> a[i];
		if (a[i] <= 0)
			a[i] = 1;
	}

	for (int i = 0; i < 10; i++)
		cout << "X[" << i << "] = " << a[i] << endl;

	return 0;
}

数组填充

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int a[10];
	int v;

	cin >> v;
	a[0] = v;

	for (int i = 1; i < 10; i++)
	{
		a[i] = a[i - 1] * 2;
	}
	
	for (int i = 0; i < 10; i++)
		printf("N[%d] = %d\n", i, a[i]);

	return 0;
}

数组选择

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a[100];
	int b[100];
	int j = 0;

	for (int i = 0; i < 100; i++)
	{
		scanf_s("%lf", &a[i]);

		if (a[i] <= 10)
		{
			b[j++] = i;
		} 
	}

	for (int i = 0; i < j; i++)
	{
		printf("A[%d] = %.1lf\n", b[i], a[b[i]]);
	}

	return 0;
}

数组中的行

#include <iostream>

using namespace std;

int main()
{
	double a[12][12];

	int l;
	char c;

	cin >> l;
	cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			cin >> a[i][j];

	if (c == 'S')
	{
		double sum = 0;
		for (int j = 0; j < 12; j++)
			sum += a[l][j];
		printf("%.1lf\n", sum);
	}

	if (c == 'M')
	{
		double sum = 0;
		for (int j = 0; j < 12; j++)
			sum += a[l][j];
		printf("%.1lf\n", sum / 12);
	}

	return 0;
}

数组的右上半部分

#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
	double a[12][12];
	char c;

	scanf_s("%c", &c);
	// cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			scanf_s("%lf", &a[i][j]);
			// cin >> a[i][j];

	double sum = 0;
	int count = 0;
	
	for (int i = 0; i < 12; i++)
		for (int j = i + 1; j < 12; j++)
		{
			sum += a[i][j];
			count++;
		}

	if (c == 'S')
		printf("%.1lf\n", sum);
	if (c == 'M')
		printf("%.1lf\n", sum / count);

	return 0;
}

数组的左上半部分

#include <cstdio>

int main()
{
	double a[12][12];
	char c;

	scanf_s("%c", &c);

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			scanf_s("%lf", &a[i][j]);

	double sum = 0;
	int count = 0;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 11 - i; j++)
		{
			sum += a[i][j];
			count++;
		}

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / count);

	return 0;
}

数组的上方区域

#include <cstdio>

int main()
{
	double a[12][12];
	char c;

	scanf_s("%c", &c);

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			scanf_s("%lf", &a[i][j]);

	int count = 0;
	double sum = 0;

	for (int i = 0; i < 5; i++)
	{
		for (int j = i + 1; j < 11 - i; j++)
		{
			sum += a[i][j];
			count++;
		}
	}

	if (c == 'S')
		printf("%.1lf\n", sum);
	if (c == 'M')
		printf("%.1lf\n", sum / count);

	return 0;
}

数组的左方区域

#include <cstdio>

int main()
{
	double a[12][12];
	char c;

	scanf_s("%c", &c);

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			scanf_s("%lf", &a[i][j]);

	int count = 0;
	double sum = 0;

	for (int i = 0; i < 6; i++)
		for (int j = 0; j < i; j++)
		{
			count++;
			sum += a[i][j];
		}
	for (int i = 6; i < 11; i++)
		for (int j = 0; j < 11 - i; j++)
		{
			count++;
			sum += a[i][j];
		}

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / count);

	return 0;
}

平方矩阵

#include <iostream>

using namespace std;

int main()
{
	int n;
	int a[100][100];

	while (cin >> n && n)
	{
		int start = 0;
		int end = 1;

		for (int k = 0; k < n / 2; k++)
		{
			for (int i = k; i <= n - end; i++)
			{
				for (int j = k; j <= n - end; j++)
				{
					if (i == start || j == start || i == n - end || j == n - end)
						a[i][j] = start + 1;
					else
					    a[i][j] = 0;// 这一行是调试看结果用的。
				}
			}
			start++;
			end++;
		}

		if (n % 2 * 10 != 0)
			a[(n + 1) / 2 - 1][(n + 1) / 2 - 1] = (n + 1) / 2;

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
				cout << a[i][j] << ' ';
			cout << endl;
		}
		cout << endl;
	}

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int n;

	while (cin >> n, n)
	{
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
				int up = i;
				int down = n - i + 1;
				int left = j;
				int right = n - j + 1;
				
				int m = min(up, down);
				m = min(left, m);
				m = min(right, m);

				cout << m << ' ';
			}
			cout << endl;
		}
		cout << endl;
	}

	return 0;
}

数组变换

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	int a[20];

	for (int i = 0; i < 20; i++)
		cin >> a[i];

	reverse(a, a + 20);

	for (int i = 0; i < 20; i++)
		cout << "N[" << i << "] = " << a[i] << endl;

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[20], b[20];

	for (int i = 0; i < 20; i++)
		cin >> a[i];

	for (int i = 19, j = 0; i >= 0; i--, j++)
		b[j] = a[i];
	
	for (int i = 0; i < 20; i++)
		cout << "N[" << i << "] = " << b[i] << endl;

	return 0;
}

斐波那契数列

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int sum;
	int n;

	cin >> sum;

	for (int i = 1; i <= sum; i++)
	{
		cin >> n;

		double a = 0;
		double b = 1;
		for (int j = 0; j < n; j++)
		{
			double temp = a;
			a = b;
			b = temp + b;
		}
		printf("Fib(%d) = %.0lf\n", n, a);
	}

	return 0;
}

最小数和它的位置

#include <iostream>

using namespace std;

int main()
{
	int n;
	int a[1000];
	int min = 0;

	cin >> n;

	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		if (a[i] < a[min])
			min = i;
	}

	cout << "Minimum value: " << a[min] << endl;
	cout << "Position: " << min << endl;

	return 0;
}

数组中的列

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a[12][12];
	int n;
	char c;
	double sum = 0;

	cin >> n;
	cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			cin >> a[i][j];

	for (int i = 0; i < 12; i++)
		sum += a[i][n];

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / 12);

	return 0;
}

数组的右下半部分

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a[12][12];
	char c;
	double sum = 0;
	int count = 0;

	cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			cin >> a[i][j];

	for (int i = 0; i < 12; i++)
		for (int j = 12 - i; j < 12; j++)
		{
			sum += a[i][j];
			count++;
		}

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / count);

	return 0;
}

数组的左下半部分

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	char c;
	double a[12][12];
	double sum = 0;
	int count = 0;

	cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			cin >> a[i][j];

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < i; j++)
		{
			sum += a[i][j];
			count++;
		}

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / count);
	
	return 0;
}

数组的下方区域

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a[12][12];
	char c;
	double sum = 0;
	int count = 0;

	cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			cin >> a[i][j];

	for (int i = 7; i < 12; i++)
	{
		for (int j = 12 - i; j < 6; j++)
		{
			sum += a[i][j];
			count++;
		}
		for (int j = 6; j < i; j++)
		{
			sum += a[i][j];
			count++;
		}
	}

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / count);

	return 0;
}

数组的右方区域

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	double a[12][12];
	char c;
	int count = 0;
	double sum = 0;

	cin >> c;

	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			cin >> a[i][j];

	for (int i = 1; i < 6; i++)
	{
		for (int j = 12 - i; j < 12; j++)
		{
			sum += a[i][j];
			count++;
		}
	}
	for (int i = 6; i < 11; i++)
	{
		for (int j = i + 1; j < 12; j++)
		{
			sum += a[i][j];
			count++;
		}
	}

	if (c == 'S')
		printf("%.1lf", sum);
	if (c == 'M')
		printf("%.1lf", sum / count);

	return 0;
}

平方矩阵 II

#include <iostream>

using namespace std;

int main()
{
	int n;
	int a[100][100];

	while (cin >> n, n)
	{
		for (int k = 0; k < n; k++)
		{
			int xx = 1;
			int yy = 1;
			for (int i = k; i < n; i++)
			{
				for (int j = k; j < n; j++)
				{
					if (i == k)
						a[i][j] = xx++;
					if (j == k)
						a[i][j] = yy++;
				}
			}
		}

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
				cout << a[i][j] << ' ';
			cout << endl;
		}
		cout << endl;
	}
	
	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[100][100];
	int n;

	while (cin >> n, n)
	{
		for (int i = 0; i < n; i++)
		{
			a[i][i] = 1;
			for (int j = i + 1; j < n; j++)
			{
				a[i][j] = ++a[i][i];
				a[j][i] = a[i][j];
			}
			a[i][i] = 1;
		}
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
				cout << a[i][j] << ' ';
			cout << endl;
		}
		cout << endl;
	}

	return 0;
}

平方矩阵 III

#include <iostream>

using namespace std;

int main()
{
	int n;
	int a[15][15];

	while (cin >> n, n)
	{
		a[0][0] = 1;
		for (int i = 0; i < n; i++)
		{
			if (i > 0)
				a[i][i] = a[i - 1][i - 1] * 4;
			for (int j = i + 1; j < n; j++)
			{
				a[i][j] = a[i][j - 1] * 2;
				a[j][i] = a[i][j];
			}
		}

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
				cout << a[i][j] << ' ';
			cout << endl;
		}
		cout << endl;
	}

	return 0;
}

蛇形矩阵

#include <iostream>

using namespace std;

int main()
{
	int n;
	int m;
	int a[100][100];

	cin >> n >> m;

	int count = 1;

	int _min = min(n, m);
	int circle;

	if (_min % 2)
		circle = _min / 2 + 1;
	else
		circle = _min / 2;

	for (int k = 0; k < circle; k++)
	{
		for (int i = k; i < k + 1; i++)// 左上->右上
		{
			for (int j = k; j < m - k; j++)
				a[i][j] = count++;
			count--;
		}
		for (int i = k; i < n - k; i++)// 右上->右下
		{
			for (int j = m - 1 - k; j < m - k; j++)
				a[i][j] = count++;
		}
		count--;
		for (int i = n - 1 - k; i < n - k; i++)// 右下->左下
		{
			if (!(n % 2) || i != n / 2)
			{
				for (int j = m - 1 - k; j >= k; j--)
					a[i][j] = count++;
				count--;
			}
		}
		for (int i = n - 1 - k; i >= k + 1; i--)// 左下->左上
		{
			for (int j = k; j < 1 + k; j++)
				if (!(m % 2) || j != m / 2)
				{
					a[i][j] = count++;
				}
		}
	}

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
			cout << a[i][j] << ' ';
		cout << endl;
	}

	return 0;
}

使用偏移量来解题

#include <iostream>

using namespace std;

int res[100][100];// 全局变量,数组中未赋值的数一定都是0

int main()
{
	int n, m;
	// int res[100][100] = { };// 局部变量,这样写也可以把数组的初始值全部赋为0
    
	cin >> n >> m;

	int dx[] = { 0, 1, 0, -1 };
	int dy[] = { 1, 0, -1, 0 };

	for (int x = 0, y = 0, d = 0, k = 1; k <= n * m; k++)
	{
		res[x][y] = k;
		int a = x + dx[d];
		int b = y + dy[d];
		if (a < 0 || a >= n || b < 0 || b >= m || res[a][b])
		{
			d = (d + 1) % 4;// 感受这行代码的魅力
			a = x + dx[d];
			b = y + dy[d];
		}
		x = a;
		y = b;
	}

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
			cout << res[i][j] << ' ';
		cout << endl;
	}

	return 0;
}

字符串

  • 字符串是计算机与人类沟通的重要手段
#include <iostream>

using namespace std;

int main()
{
	char c = 'a';

	cout << (int)c << endl;

	cout << (char)97 << endl;

	return 0;
}
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	for (int i = 0; i < 128; i++)
		printf("%d: %c\n", i, (char)i);

	return 0;
}
  • 常用的ASCII值:‘A’-'Z’是65-90、‘a’-'z’是97-122、‘0’-'9’是48-57

  • 字符本质上存在计算机中是数字,可以做运算,只有在显示到屏幕上时才会是字符的形式显示

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	printf("%d\n", 'b' - 'a');
	printf("%c\n", 'a' + 3);

	int a = 'A' + 'B';
	int b = 'A' * 'B';

	char c = 'A' + 2;

	printf("%d\n", a);
	printf("%d\n", b);

	printf("%c", c);

	return 0;
}
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	char c;
	int nums = 0;
	int chars = 0;

	while (cin >> c)
	{
		if (c >= '0' && c <= '9')
			nums++;
		else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
			chars++;
	}

	printf("nums:%d\n", nums);
	printf("chars:%d\n", chars);

	return 0;
}
  • 字符串就是字符数组加上结束符’\0’
  • ‘\0’ 对应的ASCII码值为 0
  • 我们可以使用字符串来初始化字符数组,但此时要注意,每个字符串结尾会暗含一个’\0’字符,因此字符数组的长度至少要比字符串的长度多1
#include <iostream>

using namespace std;

int main()
{
	char a1[] = { 'C', '+', '+' };// 因为没有'\0',所以这个字符数组不能被称为一个字符串
	char a2[] = { 'C', '+', '+', '\0' };// 可以被称为一个字符串
	char a3[] = "C++";// a3[] 和 a2[] 的字符数组初始化是等价的
	// char a4[6] = "Daniel";// 这一行会报错,因为数组长度不够

	cout << sizeof a1 << endl;
	cout << sizeof a2 << endl;
	cout << sizeof a3 << endl;

	return 0;
}
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	char a1[] = { 'C', '+', '+' };
	char a2[] = { 'C', '+', '+', '\0' };
	char a3[] = "C++";
	char a4[] = { 'A', 'B', 'C', '\0' };

	cout << a3 << endl;
	printf("%s\n", a3);
	printf("%s\n", a2);

	cout << a4 << endl;// 从数组下标为0开始输出
	cout << a4 + 1 << endl;// 从数组下标为1开始输出

	return 0;
}
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	char s[100];

	// scanf_s("%s", s);// 注意!读入字符数组时,这里的s千万不要加取地址符号&
	// cin >> s;
	cin >> s + 1;// 这个表示从字符数组下标为1的位置开始存储字符
	// 注意:这里的字符数组,读入的时候遇到 空格、回车、结束符 会停止读入。
	/*
		读入一行元素的方法是:
		1、fgets(s, 100, stdin);
		2、getline(cin, s); 注意这里的s必须为string类型,而不能是字符数组类型
	*/

	cout << "==========" << endl;
	cout << s + 1 << endl;

	return 0;
}
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	char s[100];

	fgets(s, 1000000, stdin);// 字符数组可以用这个实现读入一整行元素,包括 空格 和 回车('\n') 也能读入

	cout << s << endl;

	return 0;
}
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main()
{
	string s;

	getline(cin, s);// 可以读入一整行元素,s必须为字符串类型

	cout << s << endl;

	return 0;
}
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main()
{
	char s[100];

	cin.getline(s, 100);// 字符数组也可以用这个实现读入一整行元素。第二个参数表示最多读入多少个字符

	cout << s << endl;

	return 0;
}
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main()
{
	char s[100];

	scanf_s("%s", s);

	puts(s);// 等价于下面那行代码,puts自带换行符
	printf("%s\n", s);

	return 0;
}
  • 常用的三个函数,参数的类型必须为字符数组
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int main()
{
	char a[100];
	char b[100];
	char c[100];

	scanf_s("%s", a);
	scanf_s("%s", b);

	cout << strlen(a) << endl;// 求字符数组的长度,'\0'结束符不计入长度
	
	// a小于b,返回 a的ascll码值 减去 b的ascll码值 的结果
	// a等于b,返回0
	// a大于b,返回 a的ascll码值 减去 b的ascll码值 的结果
	// 这里的比较方式是:字典序
	cout << strcmp(a, b) << endl;

	cout << strcpy(c, b) << endl;// 把b字符数组复制给c字符数组

	return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int main()
{
	char a[100];

	scanf_s("%s", a);

	/*
	for (int i = 0; i < strlen(a); i++)// 这里相当于两重循环,效率很慢
		cout << a[i] << endl;
	*/
	for (int i = 0, len = strlen(a); i < len; i++)
		cout << a[i] << endl;

	return 0;
}

我们一般很少用字符数组去处理字符串,大多数情况下我们都是直接使用string类型

  • 标准库类型 string
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1;// 默认为空字符串

	string s2 = s1;// s1字符串 赋值给 s2字符串(s2是s1的一个副本)

	string s3 = "hiya";// s3是该字符串字面值的一个副本

	string s4(10, 'c');// s4的内容是:cccccccccc

	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1, s2;

	cin >> s1;// 注意:string类型的变量不能用scanf来读入
	cin >> s2;

	cout << s1 << endl;
	printf("%s\n", s1.c_str());// 这样也能输出字符串
	cout << s2 << endl;

	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1 = "abc", s2;

	cout << s1.empty() << endl;// 返回0,则表示字符串不为空
	cout << s2.empty() << endl;// 返回1,则表示字符串为空

	/*
		string 的 size() 函数的时间复杂度为 O(1)
		strlen() 函数的时间复杂度为 O(n)
	*/
	cout << s1.size() << endl;// 返回字符串的长度
	cout << s2.size() << endl;

	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1, s2;

	// string的比较支持以下的比较方式,是按照字典序进行比较的
	if (s1 == s2);
	if (s1 != s2);
	if (s1 > s2);
	if (s1 >= s2);
	if (s1 < s2);
	if (s1 <= s2);
	
	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1 = "hello,", s2 = "world";

	string s3 = s1 + s2;

	s3 += s1;

	s3 = s3 + " is great " + 'a';

	cout << s3 << endl;

	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1 = "hello";
	string s2 = "world";
	
	string s3 = s1 + s2;

	string s4 = s1 + ", " + s2 + '!';

	/*
		当把 string对象 和 字符字面值 及 字符串字面值 混在一条语句中使用时,
		必须确保每个加法运算符的两侧的对象至少有一个是 string对象,
		不然语句会报错
	*/
	// string s5 = "hello" + "world";// 这一行会报错,因为不满足规则
	string s6 = s1 + ", " + "world" + '!';// 这一行不会报错,因为从左到右,s1和", "相加后会转成string对象,满足规则

	cout << s3 << endl;
	cout << s4 << endl;
	cout << s6 << endl;

	return 0;
}
  • 处理string对象中的字符
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1 = "Hello World!";

	for (int i = 0; i < s1.size(); i++)// 把字符串当成字符数组
		cout << s1[i] << endl;
	
	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1 = "Hello World!";

	for (char c : s1)
		cout << c << endl;
		
	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	string s1 = "Hello World!";

	for (char c : s1)
		c = 'a';
	cout << s1 << endl;

	for (char &c : s1)// 加上 & 这样能实现改变c的值,同时改变s1字符串的值
		c = 'b';
	cout << s1 << endl;
		
	return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	auto s1 = "Hello World!";// auto 是让编译器去猜类型
	string s2 = "ABCD";

	cout << s1 << endl;
	// cout << s1.size() << endl;// 这一行报错是因为,编译器把 s1 的类型猜为 char s1[] 字符数组类型了
		
	for (auto c : s2)// 这里编译器一定能够猜对类型
		cout << c << endl;

	// 能让编译器一定能够猜对类型的情况下,用auto去代替类型名称

	return 0;
}

习题

字符串长度

#include <string>
#include <iostream>

using namespace std;

int main()
{
	string str;

	getline(cin, str);

	cout << str.size() << endl;

	return 0;
}

字符串中的数字个数

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str;

	getline(cin, str);

	int count = 0;

	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] >= '0' && str[i] <= '9')
			count++;
	}

	cout << count << endl;

	return 0;
}

循环相克令

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str1, str2;
	int n;

	cin >> n;

	while (n--)
	{
		cin >> str1;
		cin >> str2;

		if (str1 > str2)
		{
			if (str1 == "Hunter" && str2 == "Bear")
				cout << "Player2" << endl;
			else
				cout << "Player1" << endl;
		}
		else if (str1 < str2)
		{
			if (str1 == "Bear" && str2 == "Hunter")
				cout << "Player1" << endl;
			else
				cout << "Player2" << endl;
		}
		else
			cout << "Tie" << endl;
	}

	return 0;
}

字符串加空格

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str1;
	string str2;

	getline(cin, str1);

	for (int i = 0; i < str1.size(); i++)
	{
		char temp1 = str1[i];
		char temp2 = ' ';
		str2 += temp1;
		str2 += temp2;
	}

	cout << str2 << endl;

	return 0;
}

替换字符

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	char str[31];
	char a;

	cin >> str;
	cin >> a;

	for (int i = 0; str[i]; i++)
	{
		if (str[i] == a)
			str[i] = '#';
	}		

	cout << str << endl;

	return 0;
}

字符串插入

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str;
	string substr;

	while (cin >> str && cin >> substr)
	{
		int max_index = 0;
		for (int i = 0; i < str.size(); i++)
		{
			if (str[i] > str[max_index])
				max_index = i;
		}
		string temp;
		for (int i = 0; i <= max_index; i++)
			temp = temp + str[i];
		for (int i = 0; i < 3; i++)
			temp = temp + substr[i];
		for (int i = max_index + 1; i < str.size(); i++)
			temp = temp + str[i];
		cout << temp << endl;
	}
	
	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	string a, b;

	while (cin >> a >> b)
	{
		int p = 0;
		for (int i = 1; i < a.size(); i++)
			if (a[i] > a[p])
				p = i;

		// substr(x, y) 这个函数返回从下标 x 开始的长度为 y 的字符串
		// substr(x) 这个函数返回从下标 x 开始一直到最后的字符串
		// cout << a.substr(0, p + 1) + b + a.substr(p + 1, a.size() - p + 1) << endl;
		cout << a.substr(0, p + 1) + b + a.substr(p + 1) << endl;
	}

	return 0;
}

只出现一次的字符

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	char a[100001];
	int b[26] = { 0 };
	int order[26];
	int j = 0;

	cin >> a;

	for (int i = 0, len = strlen(a); i < len; i++)
	{
		int index;
		index = a[i] - 'a';
		b[index]++;
		if (b[index] == 1)
		{
			order[j] = i;
			j++;
		}
	}

	int exit = 0;
	for (int i = 0; i < 26; i++)
	{
		if (b[i] == 1)
			exit = 1;
	}
	
	if (exit)
	{
		for (int i = 0; i <= j; i++)
		{
			int k = order[i];
			int index = a[k] - 'a';
			if (b[index] == 1)
			{
				cout << a[k] << endl;
				break;
			}
		}
	}
	else
		cout << "no" << endl;

	return 0;	
}

字符串匹配

#include <iostream>

using namespace std;

int main()
{
	double a;
	string x;
	string y;

	cin >> a;
	cin >> x;
	cin >> y;

	double count = 0;

	for (int i = 0; i < x.size(); i++)
		if (x[i] == y[i])
			count++;

	if (count / x.size() >= a)
		cout << "yes" << endl;
	else
		cout << "no" << endl;

	return 0;
}

忽略大小写比较字符串大小

  • 这道题目对应的答案有点问题。答案是全部转成小写然后再去比较。

  • 正确思路应该是不同的英文字母直接比较,而不能都转成小写然后再去比较

    • **例如: ‘X’<‘f’ 如果都转成小写再去比较则结果变成了: ‘x’>‘f’ **
  • 以下是全部转成小写然后再去比较

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
	char a[81], b[81];

	cin.getline(a, 100);
	cin.getline(b, 100);

	for (int i = 0, len = strlen(a); i < len; i++)
		if (a[i] >= 'A' && a[i] <= 'Z')
			a[i] += 32;

	for (int i = 0, len = strlen(b); i < len; i++)
		if (b[i] >= 'A' && b[i] <= 'Z')
			b[i] += 32;

	if (strcmp(a, b) > 0)
		cout << '>' << endl;
	else if (strcmp(a, b) < 0)
		cout << '<' << endl;
	else
		cout << '=' << endl;

	return 0;
}
  • 以下是不同的英文字母直接比较,而不是都转成小写然后再去比较
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string a;
	string b;

	getline(cin, a);
	getline(cin, b);

	int diff = 'a' - 'A';
	int count = 0;
	char _char;

	for (int i = 0, j = 0; i < a.size() && j < b.size(); i++, j++)
	{
		if ((a[i] > b[j] && a[i] - diff == b[j]) || a[i] == b[j] || (a[i] < b[j] && b[j] - diff == a[i]))
			count++;
		else if (a[i] > b[j])
		{
			_char = '>';
			break;
		}
		else
		{
			_char = '<';
			break;
		}
	}

	if (a.size() == b.size() && count == a.size())
		cout << '=' << endl;
	else if (a.size() > b.size() && count == b.size())
		cout << '>' << endl;
	else if (a.size() < b.size() && count == a.size())
		cout << '<' << endl;
	else 
	    cout << _char << endl;

	return 0;
}

去掉多余的空格

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str;
	string finalstr;

	getline(cin, str);

	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] != ' ')
			finalstr = finalstr + str[i];
		else
		{
			finalstr = finalstr + ' ';
			int j = i;
			while (str[j++] == ' ')
				i++;
			i--;
		}
	}

	cout << finalstr << endl;

	return 0;
}

信息加密

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str;

	getline(cin, str);

	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] >= 'A' && str[i] <= 'Z')
		{
			if (str[i] == 'Z')
				str[i] = 'A';
			else
				str[i] = str[i] + 1;
		}
		if (str[i] >= 'a' && str[i] <= 'z')
		{
			if (str[i] == 'z')
				str[i] = 'a';
			else
				str[i] = str[i] + 1;
		}
	}

	cout << str << endl;

	return 0;
}
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str;

	getline(cin, str);

    for (auto &c : str)
    {
        if (c >= 'a' && c <= 'z')
            c = (c - 'a' + 1) % 26 + 'a';
        if (c >= 'A' && c <= 'Z')
            c = (c - 'A' + 1) % 26 + 'A';
    }
	cout << str << endl;

	return 0;
}

输出字符串

#include <string>
#include <iostream>

using namespace std;

int main()
{
	string a;
	string b;

	getline(cin, a);

	for (int i = 0; i < a.size(); i++)
	{
		int j = (i + 1) % a.size();
		int temp = a[i] + a[j];
		b = b + (char)temp;
	}

	cout << b << endl;

	return 0;
}

单词替换

#include <string>
#include <iostream>

using namespace std;

int main()
{
	string str;
	string a;
	string b;
	string finalstr;

	getline(cin, str);
	cin >> a;
	cin >> b;

	for (int i = 0; i < str.size(); i++)
	{
		int j = i;
		int count = 0;
		int k = 0;
		if (str[i] != a[k])
		{
			finalstr += str[i];
		}
		else
		{
			while (str[j] == a[k] && k < a.size())
			{
				k++;
				j++;
				count++;
			}
			if (count == a.size() && (str[j] == ' ' || str[j] == 0) && (str[j - count - 1] == ' ' || str[j - count - 1] == 0))
			{
				finalstr += b;
				i = j - 1;
			}
			else
				finalstr += str[i];
		}
	}

	cout << finalstr << endl;

	return 0;
}
#include <string>
#include <iostream>
#include <sstream>

using namespace std;

int main()
{
	string s, a, b;

	getline(cin, s);
	cin >> a >> b;

	// stringstream 字符串流类型
	// ssin(s) 把字符串 s 转换成字符串流
	stringstream ssin(s);

	string str;
	while (ssin >> str)// 从字符串流中读出内容赋值给 str 字符串,以字符串流的空格作为分隔
	{
		if (str == a)
			cout << b << ' ';
		else
			cout << str << ' ';
	}

	return 0;
}

知识点补充

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
	string s;// 这里的 s 为字符串

	getline(cin, s);

	// stringstream ssin(s);// ssin 这个名字可以任意取
	stringstream abc(s);

	int a, b;
	string str;
	double c;

	abc >> a >> str >> b >> c;

	cout << a << endl << str << endl << b << endl << c << endl;

	return 0;
}
#include <cstdio>
#include <iostream>
#include <sstream>

using namespace std;

int main()
{
	char s[100];// 这里的 s 为字符数组

	fgets(s, 1000, stdin);

	int a, b;
	char str[1000];
	double c;

	sscanf_s(s, "%d %s %d %lf", &a, str, &b, &c);// sscanf 的用法和 stringstream 的用法类似

	cout << a << endl << str << endl << b << endl << c << endl;
	
	return 0;
}

字符串中最长的连续出现的字符

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int n;

	cin >> n;

	string str;
	int _char[128] = { 0 };

	while (n--)
	{
		cin >> str;
		int j;
		for (int i = 0; i < str.size(); i++)
		{
			int cnt = 0;
			cnt++;
			j = i;
			while (str[++j] == str[i])
				cnt++;
			if (cnt > _char[str[i]])
				_char[str[i]] = cnt;
			i = j - 1;
		}
		int max = _char[1];
		for (int i = 1; i < 128; i++)
		{
			if (_char[i] > max)
				max = _char[i];
		}
		int max_index = 0;
		for (int i = 0; i < str.size(); i++)
		{
			int flag = 1;
			if (_char[str[i]] == max)
			{
				for (int j = 0; j < max; j++)
				{
					if (str[i] != str[i + j])
					{
						flag = 0;
						break;
					}
				}
				if (flag)
				{
					max_index = i;
					break;
				}
			}
		}
		cout << (char)str[max_index] << " " << max << endl;
		for (int i = 1; i < 128; i++)
			_char[i] = 0;
	}

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int n;

	cin >> n;

	while (n--)
	{
		int cnt = 0;
		char c = 0;
		string str;
		cin >> str;

		for (int i = 0; i < str.size(); i++)
		{
			int j = i;
			while (j < str.size() && str[j] == str[i])
				j++;
			if (j - i > cnt)
			{
				cnt = j - i;
				c = str[i];
			}
			i = j - 1;
		}
		cout << c << " " << cnt << endl;
	}

	return 0;
}

最长单词

#include <string>
#include <iostream>

using namespace std;

int main()
{
	string str;

	getline(cin, str);

	int cnt = 0;
	int index = 0;
	for (int i = 0; i < str.size() - 1; i++)
	{
		int j = i;
		while (j < str.size() - 1 && str[j] != ' ')
			j++;
		if (j - i > cnt)
		{
			cnt = j - i;
			index = i;
		}
		if (str[i] != ' ')
			i = j - 1;
	}

	for (int i = index; i < index + cnt; i++)
		cout << str[i];

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	string res, str;

	while (cin >> str)
	{
		if (str.back() == '.')// str.back() 返回字符串最后一个位置(不包括结束符)的字符
			str.pop_back();// str.pop_back() 去掉字符串的最后一个字符
		if (str.size() > res.size())
			res = str;
	}

	cout << res << endl;

	return 0;
}

倒排单词

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
	string str;

	getline(cin, str);

	stringstream ssin(str);

	string str_res[51];
	int i = 0;
	while (ssin >> str_res[i])
		i++;
	for (int j = i - 1; j >= 0; j--)
		cout << str_res[j] << ' ';

	return 0;
}

字符串移位包含问题

#include <iostream>

using namespace std;

int main()
{
	string str1;
	string str2;

	cin >> str1 >> str2;

	if (str1.size() >= str2.size())
	{
		for (int i = 0; i < str1.size(); i++)
		{
			int j = i;
			int k = 0;
			int cnt = 0;
			if (str1[j] == str2[k])
			{
				while (str1[j] == str2[k])
				{
					j = (j + 1) % str1.size();
					k = (k + 1) % str2.size();
					cnt++;
					if (cnt == str2.size())
					{
						cout << "true" << endl;
						return 0;
					}
				}
			}
		}
	}
	else {
		for (int i = 0; i < str1.size(); i++)
		{
			int j = 0;
			int k = i;
			int cnt = 0;
			if (str1[j] == str2[k])
			{
				while (str1[j] == str2[k])
				{
					j = (j + 1) % str1.size();
					k = (k + 1) % str2.size();
					cnt++;
					if (cnt == str1.size())
					{
						cout << "true" << endl;
						return 0;
					}
				}
			}
		}
	}

	cout << "false" << endl;

	return 0;
}

字符串乘方

#include <iostream>

using namespace std;

int main()
{
	string str;

	while (cin >> str, str != ".")
	{
		int max = 0;
		for (int k = 1; k <= str.size(); k++)
		{
			string temp;
			int cnt = 0;
			while (temp.size() < str.size())
			{
				temp = temp + str.substr(0, k);
				cnt++;
				if (temp == str)
				{
					if (cnt > max)
					{
						max = cnt;
						cout << max << endl;
						break;
					}
				}
			}
		}
	}

	return 0;
}

字符串最大跨距

#include <iostream>

using namespace std;

int main()
{
	string str;
	string a;
	string b;

	cin >> str;
	int comma[2];
	int n = 0;
	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] == ',')
			comma[n++] = i;
	}
	a = str.substr(comma[0] + 1, comma[1] - comma[0] - 1);
	b = str.substr(comma[1] + 1);
	str = str.substr(0, comma[0]);

	int left_index;
	for (int i = 0; i < str.size(); i++)
	{
		int j = i;
		int k = 0;
		int cnt = 0;
		while (str[j] == a[k] && k < a.size() && j < str.size())
		{
			k++;
			j++;
			cnt++;
		}
		if (cnt == a.size())
		{
			left_index = j - 1;
			break;
		}
	}
	int right_index;
	for (int i = str.size() - 1; i >= 0; i--)
	{
		int j = i;
		int k = b.size() - 1;
		int cnt = 0;
		while (str[j] == b[k] && k >= 0 && j >= 0)
		{
			k--;
			j--;
			cnt++;
		}
		if (cnt == b.size())
		{
			right_index = j + 1;
			break;
		}
	}
	if (left_index < right_index)
		cout << right_index - left_index - 1 << endl;
	else
		cout << "-1" << endl;

	return 0;
}

知识点补充

  • 如下可以实现输入用逗号隔开的字符串
#include <iostream>
 
using namespace std;

int main()
{
	string s, s1, s2;

	char c;
	while (cin >> c, c != ',') s += c;
	while (cin >> c, c != ',') s1 += c;
	while (cin >> c) s2 += c;

	cout << s << endl;
	cout << s1 << endl;
	cout << s2 << endl;

	return 0;
}

最长公共字符串后缀

#include <iostream>

using namespace std;

int main()
{
	int n;

	while (cin >> n, n)
	{
		string str[200];
		for (int i = 0; i < n; i++)
			cin >> str[i];
		int suffix_len = 201;
		for (int i = 0; i < n; i++)
		{
			if (str[i].size() < suffix_len)
				suffix_len = str[i].size();
		}
		string suffix;
		for (int k = 1; k <= suffix_len; k++)
		{
			int j = 0;
			int cnt = 0;
			while (j < n - 1 && str[j][str[j].size() - k] == str[j + 1][str[j + 1].size() - k])
			{
				j++;
				cnt++;
			}
			if (cnt == (n - 1))
				suffix = str[0][str[0].size() - k] + suffix;
			else
				break;
		}
		cout << suffix << endl;
	}

	return 0;
}

函数

  • 函数让代码变得更加简洁
#include <iostream>

using namespace std;

void foo()
{
	cout << "Hello World!" << endl;
}

int main()
{
	foo();

	return 0;
}
#include <iostream>

using namespace std;

// 函数的声明
int foo(int n);
// int foo(int);// 在函数的声明中变量名可以不写

// 函数的定义
int foo(int n)
{
	int res = 1;
	for (int i = 1; i <= n; i++)
		res = res * i;
	return res;
}

void output()
{
	// 静态变量:在函数内部只会被创建一次
	static int cnt = 0;// 静态变量的初始化只会在第一次调用函数的时候会被执行

	// 静态变量可以理解为是在函数内部开了一个只有该函数本身可以使用的全局变量

	/*
		静态变量和局部变量都是开到堆空间里面的。
		如果要定义一个长度为一百万的数组,则要开在堆空间中,堆空间比较充足。
	*/
	cout << "call: " << ++cnt << endl;
}

int main()
{
	cout << foo(5) << endl;

	output();
	output();
	output();
	output();
	output();

	return 0;
}
#include <iostream>

using namespace std;

int foo(int a, int b = 10)// 如果没有给b传递值,则b的默认值为10
{
	cout << a << ' ' << b << endl;

	return 0;
}

int main()
{
	foo(5);
	foo(11, 54);

	return 0;
}
#include <iostream>

using namespace std;

int max(int x, int y)// 普通类型的参数传递
{
	x = 10;
	y = 20;

	if (x > y) 
		return x;
	return y;
}

int main()
{
	int a, b;

	cin >> a >> b;

	cout << max(a, b) << endl;
	cout << a << ' ' << b << endl;

	return 0;
}
#include <iostream>

using namespace std;

int max(int &x, int &y)// 引用类型的参数传递
{
	x = 10;
	y = 20;

	if (x > y) 
		return x;
	return y;
}

void swap(int &x, int &y)
{
	int temp;
	temp = y;
	y = x;
	x = temp;
}

int main()
{
	int a, b;
	cin >> a >> b;
	cout << max(a, b) << endl;
	cout << a << ' ' << b << endl;

	int w = 87;
	int e = 34;
	swap(w, e);
	cout << w << ' ' << e << endl;

	return 0;
}
  • 数组的传递是引用类型的参数传递
#include <iostream>

using namespace std;

// int output(int n, int a[5])
// int output(int n, int a[])
int output1(int n, int* a)// 这是指针的写法
{
	for (int i = 0; i < n; i++)
		cout << a[i] << ' ';
	cout << endl;

	return 0;
}

// int output2(int x, int y, int b[3][3])
// int output2(int x, int y, int b[][3])// 多维数组b,只有第一维的长度可以省略掉
int output2(int x, int y, int(*b)[3])
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++)
		{
			cout << b[i][j] << ' ';
			b[i][j] = 1;
		}
		cout << endl;
	}

	return 0;
}

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	output1(5, a);

	int b[3][3] = {
		{ 1, 2, 3 },
		{ 4, 5, 6 },
		{ 7, 8, 9 }
	};
	output2(3, 3, b);

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
			cout << b[i][j] << ' ';
		cout << endl;
	}

	return 0;
}
#include <iostream>

using namespace std;

void foo(int b[])
{
	cout << sizeof b << endl;

	return;// 这样写表示函数没有返回类型void
    
    cout << "Hello World!" << endl;
}

int main()
{
	int a[10];
	
	cout << sizeof a << endl;// 40 即输出的是a数组的字节长度
	foo(a);// 8 即输出的是x64架构下的指针长度,为8个字节

	return 0;
}
#include <iostream>

using namespace std;

int goo()
{
	puts("Called goo");

	return 0;
}

int foo()
{
	puts("Called foo");

	goo();

	return 0;
}

int main()
{
	foo();

	return 0;
}
#include <iostream>

using namespace std;

int fact(int n)
{
	if (n == 1)
		return 1;

	return n * fact(n - 1);
}

int main()
{
	cout << fact(5) << endl;

	return 0;
}

习题

n的阶乘

#include <iostream>

using namespace std;

int fact(int n)
{
	if (n == 1)
		return 1;
	return n * fact(n - 1);
}

int main()
{
	int n;
	cin >> n;
	cout << fact(n) << endl;
	return 0;
}

x和y的最大值

#include <iostream>

using namespace std;

int max(int x, int y)
{
	if (x > y)
		return x;
	return y;
}

int main()
{
	int x, y;
	cin >> x >> y;
	cout << max(x, y) << endl;
	return 0;
}

最大公约数

#include <iostream>

using namespace std;

int gcd(int a, int b)
{
	int min = a;
	if (b < a)
		min = b;
	int j;
	for (int i = 1; i <= (min / i); i++)
	{
		if (b % i == 0 && a % i == 0)
			j = i;
		if (b % (min / i) == 0 && a % (min / i) == 0)
			return min / i;
	}
	return j;
}

int main()
{
	int a, b;
	cin >> a >> b;
	cout << gcd(a, b) << endl;
	return 0;
}

交换数值

#include <iostream>

using namespace std;

void swap(int &x, int &y)
{
	int temp = x;
	x = y;
	y = temp;
	return;
}

int main()
{
	int a, b;
	cin >> a >> b;
	swap(a, b);
	cout << a << ' ' << b << endl;
	return 0;
}

打印数字

#include <iostream>

using namespace std;

void print(int a[], int size)
{
	for (int i = 0; i < size; i++)
		cout << a[i] << ' ';
	cout << endl;
	return;
}

int main()
{
	int n;
	int size;
	int a[1000];
	cin >> n >> size;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	print(a, size);
	return 0;
}

打印矩阵

#include <iostream>

using namespace std;

int a[100][100];

void print2D(int a[][100], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			cin >> a[i][j];
			cout << a[i][j] << ' ';
		}
		cout << endl;
	}
	return;
}

int main()
{
	int x, y;
	cin >> x >> y;
	print2D(a, x, y);

	return 0;
}

递归求阶乘

#include <iostream>

using namespace std;

int fact(int n)
{
	if (n == 1)
		return 1;
	return n * fact(n - 1);
}

int main()
{
	int n;
	cin >> n;
	cout << fact(n) << endl;
	return 0;
}

递归求斐波那契数列

#include <iostream>

using namespace std;

int fibo(int n)
{
	if (n == 1 || n == 2)
		return 1;
	return fibo(n - 1) + fibo(n - 2);
}

int main()
{
	int n;
	cin >> n;
	cout << fibo(n) << endl;
	return 0;
}

知识点补充

计算机的函数调用的过程本身就是数据结构中的树的遍历的过程

绝对值

#include <iostream>

using namespace std;

int abs(int x)
{
	if (x <= 0)
		return -(x);
	return x;
}

int main()
{
	int x;
	cin >> x;
	cout << abs(x) << endl;
	return 0;
}

两个数的和

#include <iostream>
#include <cstdio>

using namespace std;

double add(double x, double y)
{
	return x + y;
}

int main()
{
	double x, y;
	cin >> x >> y;
	printf("%.2lf", add(x, y));
	return 0;
}

区间求和

#include <iostream>

using namespace std;

int sum(int l, int r)
{
	int sum = 0;
	for (int i = l; i <= r; i++)
		sum += i;
	return sum;
}

int main()
{
	int l, r;
	cin >> l >> r;
	cout << sum(l, r) << endl;
	return 0;
}

最小公倍数

#include <iostream>

using namespace std;

int lcm(int a, int b)
{
	if (a == b)
		return a;
	int max = a;
	int min = b;
	if (b > a)
	{
		max = b;
		min = a;
	}
	int i = 1;
	int j = 1;
	while (1)
	{
		if (max * i > min * j)
			j++;
		else if (max * i == min * j)
			return max * i;
		else
			i++;
	}
}

int main()
{
	int a, b;
	cin >> a >> b;
	cout << lcm(a, b) << endl;
	return 0;
}

复制数组

#include <iostream>

using namespace std;

int a[100];
int b[100];

void copy(int a[], int b[], int size)
{
	for (int i = 0; i < size; i++)
		b[i] = a[i];
	return;
}

int main()
{
	int n, m, size;
	cin >> n >> m >> size;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
		cin >> b[i];
	copy(a, b, size);
	for (int i = 0; i < m; i++)
		cout << b[i] << ' ';
	return 0;
}

打印字符串

#include <iostream>
#include <cstring>

using namespace std;

void print(char str[])
{
	for (int i = 0, len = strlen(str); i < len; i++)
		cout << str[i];
	cout << endl;
	return;
}

int main()
{
	char str[101];
	cin.getline(str, 101);
	print(str);
	return 0;
}

数组翻转

#include <iostream>

using namespace std;

int a[1000];

void reverse(int a[], int size)
{
	int b[1000];
	for (int i = 0; i < size; i++)
		b[i] = a[i];
	for (int i = 0, j = size - 1; i < size; i++, j--)
		a[i] = b[j];
	return;
}

int main()
{
	int n, size;
	cin >> n >> size;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	reverse(a, size);
	for (int i = 0; i < n; i++)
		cout << a[i] << ' ';
	return 0;
}

数组去重

#include <iostream>

using namespace std;

int a[1000];

int get_unique_count(int a[], int n)
{
	int b[1001] = { 0 };
	for (int i = 0; i < n; i++)
		b[a[i]]++;

	int count = 0;
	for (int i = 0; i < 1001; i++)
	{
		if (b[i] != 0)
			count++;
	}
	return count;
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	cout << get_unique_count(a, n) << endl;
	return 0;
}

数组排序

#include <iostream>

using namespace std;

int a[1000];

void sort(int a[], int l, int r)
{
	for (int i = l; i <= r; i++)
	{
		for (int j = i + 1; j <= r; j++)
		{
			if (a[i] > a[j])
			{
				int temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}
	return;
}

int main()
{
	int n, l, r;
	cin >> n >> l >> r;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	sort(a, l, r);
	for (int i = 0; i < n; i++)
		cout << a[i] << ' ';
	return 0;
}

跳台阶

#include <iostream>

using namespace std;

int f(int n)
{
	if (n == 1)
		return 1;
	if (n == 2)
		return 2;
	return f(n - 1) + f(n - 2);
}

int main()
{
	int n;
	cin >> n;
	cout << f(n) << endl;
	return 0;
}
#include <iostream>

using namespace std;

int n;
int ans;

void f(int i)
{
	if (i == n)
		ans++;
	else if (i < n)
	{
		f(i + 1);
		f(i + 2);
	}
	else
		return;
}

int main()
{
	cin >> n;
	f(0);
	cout << ans << endl;
	return 0;
}

走方格

#include <iostream>

using namespace std;

int f(int x, int y)
{
	if (x == 0 || y == 0)
		return 1;
	return f(x - 1, y) + f(x, y - 1);
}

int main()
{
	int x, y;
	cin >> x >> y;
	cout << f(x, y) << endl;
	return 0;
}
#include <iostream>

using namespace std;

int ans;
int x, y;

void f(int i, int j)
{
	if (i == x && j == y)
		ans++;
	else
	{
		if (i < x)
			f(i + 1, j);
		if (j < y)
			f(i, j + 1);
	}
	return;
}

int main()
{
	cin >> x >> y;
	f(0, 0);
	cout << ans << endl;
	return 0;
}

排列

#include <iostream>
#include <cstdio>

using namespace std;

const int N = 20;
int n;

void dfs(int u, int nums[], bool _st[])
{
	if (u > n)
	{
		for (int i = 1; i <= n; i++)
			printf("%d ", nums[i]);
		puts("");
	}
	else
	{
		for (int i = 1; i <= n; i++)
		{
			if (!_st[i])
			{
				nums[u] = i;
				_st[i] = true;
				dfs(u + 1, nums, _st);
				_st[i] = false;// 还原现场
			}
		}
	}
	return;
}

int main()
{
	scanf_s("%d", &n);

	int nums[N];
	bool _st[N] = { 0 };

	dfs(1, nums, _st);

	return 0;
}

类、结构体、指针、引用

  • 类可以将变量、数组和函数完美地打包在一起

结构体和类的作用是一样的。不同点在于类默认是private,结构体默认是public

#include <iostream>

using namespace std;

// struct Person // 结构体的写法
class Person
{
	int weight;// 在类中默认是private,在结构体中默认是public

	// 类中的变量和函数被统一称为类的成员变量
	private:
		int age, height;// 没有赋值的话是随机值
		double money;

	public:
		string name;

		void say()
		{
			cout << "I'm " << name << endl;
		}

		int get_age()
		{
			return age;
		}

		void add_money(double x)
		{
			money += x;
		}

	private:
		string books[100];
}c, persons[100];// 可以这样声明类的变量c和数组persons[100]
// C++在定义类的时候后面一定要加分号

int main()
{
	// Person c;
	// Person persons[100];
	c.name = "yxc";
	cout << c.get_age() << endl;
	c.add_money(1000000);
	
	return 0;
}
#include <iostream>

using namespace std;

struct Person
{
	int age, height;
	double money;

	Person()// 如果构造函数被重载,则必须手动写出默认的构造函数
	{
	}

	Person(int _age, int _height)// 构造函数
	{
		age = _age;
		height = _height;
	}

	//Person(int _age, int _height, double _money)// 构造函数
	//{
	//	age = _age;
	//	height = _height;
	//	money = _money;
	//}

	Person(int _age, int _height, double _money) : age(_age), height(_height), money(_money) {}// 还可以这样写
};

int main()
{
	Person p1;// 这里是调用了无参构造函数
	Person p2(18, 180, 100);
	Person p3 = { 18, 180, 150 };// 初始化还可以这样写,按顺序赋值
	Person p4 = { 15, 170 };// 没有赋值的默认为0

	cout << p3.money << endl;
	cout << p4.money << endl;
	
	return 0;
}
#include <iostream>

using namespace std;

char a, b;

int main()
{
	char c = 'a', d;
	cout << (void*)&c << endl;// 返回存放'a'的内存地址的值。变量名c可以看做是内存地址的值的别名
	// 000000BFD28FF774
	cout << (void*)&d << endl;
	// 000000BFD28FF794

	cout << (void*)&a << endl;// 00007FF6A075D171
	cout << (void*)&b << endl;// 00007FF6A075D172
	
	/*
		1、堆空间的地址分配是从小到大分配
		2、栈空间的地址分配是从大到小分配
	*/

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a = 10;
	int *p = &a;// 可以读作int指针类型的变量名p
    // int* p = &a;// 这样写也可以

	cout << p << endl;// 000000722A9BF9F4
	cout << *p << endl;// 10

	*p = 20;
	cout << *p << endl;// 20
	cout << a << endl;// 20

	int **q = &p;
	cout << q << endl;// 0000002B512FFCB8
	cout << *q << endl;// 000000722A9BF9F4
	cout << **q << endl;// 20

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };

	// 数组名也是一个指针
	cout << a << endl;		     // 0000008A9278F838
	cout << (void*)&a[0] << endl;// 0000008A9278F838
	cout << (void*)&a[1] << endl;// 0000008A9278F83C
	cout << (void*)&a[2] << endl;// 0000008A9278F840
	cout << (void*)&a[3] << endl;// 0000008A9278F844
	cout << (void*)&a[4] << endl;// 0000008A9278F848

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a[5] = { 1, 3, 5, 7, 9 };

	int *p = a;

	cout << a << endl;// 0000008AEC36F508
	cout << p << endl;// 0000008AEC36F508
	cout << p + 1 << endl;// 0000008AEC36F50C

	cout << *p << endl;// 1
	cout << *(p + 1) << endl;// 3
	cout << *(p + 2) << endl;// 5
	cout << *(p + 3) << endl;// 7
	cout << *(p + 4) << endl;// 9

	int *j = &a[0];
	int *k = &a[2];

	cout << k - j << endl;// 2

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a = 10;
	
	/*
		int *p = &a;
		*p = 3;
	*/

	// 这是另外一种写法
	int &p = a;// 这个写法被称为:引用
	p = 3;

	cout << a << endl;

	return 0;
}
  • 单链表
#include <iostream>

using namespace std;

struct Node
{
	int val;
	Node* next;

	Node() {}

	Node(int _val) : val(_val), next(NULL) {}
};

int main()
{
	/*
		Node node = Node(1);// 返回值是Node类型的值
		Node* p = &node;
	*/
	// 上面的两行代码可以简写成如下一行代码
	Node* p = new Node(1);// Node(1) 前面加上一个 new 则返回值是一个地址

	// 这里相当于,指向了自己
	// p->next = p;// 规定:如果p是一个指针,则必须通过 -> 来调用结构体或类中的成员变量

	// Node* q = new Node(2);
	auto q = new Node(2);// 也可以这样写。 auto 等价于 Node*

	auto o = new Node(33);

	p->next = q;

	cout << p->next->val << endl;// 2

	q->next = o;

	cout << p->next->next->val << endl;// 33
	cout << endl;

	// 头结点:是指链表的第一个结点的地址
	Node* head = p;// 头结点的变量名一般写成 head

	// 遍历单链表
	for (Node* i = head; i != NULL; i = i->next)
		cout << i->val << endl;
	cout << endl;

	// 单链表的最前面新增一个节点
	Node* u = new Node(99);
	u->next = head;
	head = u;
	for (Node* i = head; i != NULL; i = i->next)
		cout << i->val << endl;
	cout << endl;

	// 链表的删除表示:在链表的遍历过程中把某个节点跳过,即视为删除了这个节点
	head->next = head->next->next;
	for (Node* i = head; i != NULL; i = i->next)
		cout << i->val << endl;
	cout << endl;

	return 0;
}

习题

斐波那契数列

#include <iostream>

using namespace std;

class Solution {
public:
    int Fibonacci(int n) {
        if (n == 0)
            return 0;
        if (n == 1)
            return 1;
        return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
};

int main()
{
    Solution solution;
    int n;
    cin >> n;

    cout << solution.Fibonacci(n) << endl;

    return 0;
}

替换空格

#include <iostream>
#include <string>

using namespace std;

class Solution {
public:
    string replaceSpaces(string& str) {
        string temp;
        for (int i = 0; i < str.size(); i++)
        {
            if (str[i] == ' ')
                temp = temp + "%20";
            else
                temp = temp + str[i];
        }
        return temp;
    }
};

int main()
{
    Solution solution;
    string str;
    getline(cin, str);
    cout << solution.replaceSpaces(str) << endl;
    
    return 0;
}

求1+2+…+n

#include <iostream>

using namespace std;

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while (n != 0)
        {
            sum += n;
            n--;
        }
        return sum;
    }
};

int main()
{
    Solution solution;
    int n;
    cin >> n;
    cout << solution.getSum(n) << endl;

    return 0;
}
#include <iostream>

using namespace std;

class Solution {
public:
    int getSum(int n) {
        int sum = n;
        n > 0 && (sum += getSum(n - 1));// 利用了条件表达式的短路性质
        return sum;
    }
};

int main()
{
    Solution solution;
    int n;
    cin >> n;
    cout << solution.getSum(n) << endl;

    return 0;
}

在O(1)时间删除链表结点

#include <iostream>

using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
	void deleteNode(ListNode* node) {
		/*
			node->val = node->next->val;
			node->next = node->next->next;
		*/
		// 也可以这么写
		*(node) = *(node->next);
	}
};

int main()
{
	ListNode* a = new ListNode(1);
	ListNode* b = new ListNode(4);
	ListNode* c = new ListNode(6);
	ListNode* d = new ListNode(8);

	a->next = b;
	b->next = c;
	c->next = d;

	Solution solution;
	solution.deleteNode(c);
	for (ListNode* i = a; i != NULL; i = i->next)
		cout << i->val << endl;

	return 0;	
}

合并两个排序的链表

如下代码是省略了输入和输出的代码,只实现了关键步骤

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode* a = new ListNode(-1);
        ListNode* temp = a;
        while (l1 && l2)
        {
            if (l1->val < l2->val)
            {
                temp->next = l1;
                temp = temp->next;
                l1 = l1->next;
            }
            else
            {
                temp->next = l2;
                temp = temp->next;
                l2 = l2->next;
            }
        }
        if (l1)
            temp->next = l1;
        if (l2)
            temp->next = l2;
        return a->next;
    }
};

左旋转字符串

class Solution {
public:
    string leftRotateString(string str, int n) {
        /*
            string final;
            for (int i = n; i < str.size(); i++)
                final = final + str[i];
            for (int i = 0; i < n; i++)
                final = final + str[i];
            return final;
        */
        return str.substr(n) + str.substr(0,n);
    }
};

把字符串转换成整数

class Solution {
public:
    int strToInt(string str) {
        int k = 0;
        while (k < str.size() && str[k] == ' ') 
            k++;
        long long res = 0;
        int minus = 1;
        if (str[k] == '-')
        {
            minus = -1;
            k++;
        }
        if (str[k] == '+')
            k++;
        while (k < str.size() && str[k] >= '0' && str[k] <= '9')
        {
            res = res * 10 + (str[k] - '0');// 感受这行代码的魅力
            if (res * minus > INT_MAX)
                return INT_MAX;
            if (res * minus < INT_MIN)
                return INT_MIN;
            k++;
        }
        return res * minus;
    }
};

反转链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head)// 空链表
            return head;
        ListNode* p = head;
        ListNode* q = head->next;
        p->next = NULL;
        while (q != NULL)
        {
            ListNode* temp = q->next;
            q->next = p;
            p = q;
            q = temp;
        }
        return p;
    }
};
  • 一定要能够在脑中复现出,用递归实现反转链表的过程
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next)
            return head;
        ListNode* tail = reverseList(head->next);
        head->next->next = head;
        head->next = NULL;
        return tail;
    }
};

两个链表的第一个公共结点

  • 这道题用到的思路非常巧妙:两个不同长度的链表的头指针,分别把这两个链表都遍历一次,所走过的总长度一定是一样的
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *findFirstCommonNode(ListNode *headA, ListNode *headB) {
        ListNode* p = headA;
        ListNode* q = headB;
        while (p != q)
        {
            if (p)
                p = p->next;
            else 
                p = headB;
            if (q)
                q = q->next;
            else
                q = headA;
        }
        return q;
    }
};

知识点补充

空节点的三种写法

  • 0
  • NULL
  • nullptr

删除链表中重复的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplication(ListNode* head) {
        ListNode* dummy = new ListNode(-1);// 虚拟一个结点
        dummy->next = head;
        ListNode* p = dummy;
        while (p->next)
        {
            ListNode* q = p->next;
            while (q->next && p->next->val == q->next->val)
                q = q->next;
            if (p->next == q)
                p = q;
            else
                p->next = q->next;
        }
        return dummy->next;
    }
};

STL

  • STL是提高C++编写效率的一个利器

vector

  • vector在数组结尾,插入或删除的时间复杂度都是:O(1)

  • vector在数组开头,插入或删除的时间复杂度都是:O(n)

#include <iostream>
#include <vector>

using namespace std;

struct Rec
{
	int x, y;
};

int main()
{
	vector<int> a;// 相当于定义了一个长度动态变化的int数组
	vector<int> b[233];// 相当于定义了一个一维长度为233,二维长度动态变化的int二维数组
	vector<Rec> c;
	
	// 所有的STL容器都有这两个函数:size()、empty()
	a.size();
	a.empty();

	a.clear();// 表示把当前数组的元素全部清空
    // 除了普通队列、优先队列、栈、bitset之外,所有的STL容器都有clear()函数

	// 迭代器
	vector<int>::iterator it = a.begin();// 这里的it相当于访问a[0],it可以看做是指针
	*it;// 这里的*it相当于取a[0]的值,等价于*a.begin()
	a.begin();// a.begin()返回值是第一个元素的地址
	a.end();// a.end()返回值是最后一个元素的下一个位置的地址

	return 0;
}
#include <iostream>
#include <vector>

using namespace std;

struct Rec
{
	int x, y;
};

int main()
{
	vector<int> a({ 1, 2, 3 });
	
	cout << a[0] << ' ' << *a.begin() << endl;
	cout << a[1] << ' ' << *(a.begin() + 1) << endl;
	cout << a[2] << ' ' << *(a.begin() + 2) << endl;

	// 遍历方式一:
	for (int i = 0; i < a.size(); i++)
		cout << a[i] << ' ';
	cout << endl;

	// 遍历方式二:
	// for (auto i = a.begin(); i != a.end(); i++)// 简写
	for (vector<int>::iterator i = a.begin(); i != a.end(); i++)
		cout << *i << ' ';
	cout << endl;
	
	// 遍历方式三:
	for (int x : a)
		cout << x << ' ';
	cout << endl;

	return 0;
}
#include <iostream>
#include <vector>

using namespace std;

struct Rec
{
	int x, y;
};

int main()
{
	vector<int> a({ 1, 2, 3 });
	
	// a.front()等价于a[0]、*a.begin();
	cout << a.front() << ' ' << a[0] << ' ' << *a.begin() << endl;
	// a.back()返回最后一个元素的值
	cout << a.back() << ' ' << a[a.size() - 1] << endl;

	// a.push_back(4)在a的最后一个位置添加一个元素,元素值为4
	a.push_back(4);
	for (int x : a)
		cout << x << ' ';
	cout << endl;

	// a.pop_back()删除a的最后一个元素
	a.pop_back();
	for (int x : a)
		cout << x << ' ';
	cout << endl;

	return 0;
}
  • vector也支持比较,先比较两个数组的第一个元素,按照字典序进行比较。如果一样则以此类推继续比较下去

queue

#include <iostream>
#include <queue>// 头文件queue主要包括循环队列 queue 和优先队列 priority_queue 两个容器

using namespace std;

struct Rec1
{
	int a, b;
};

struct Rec2
{
	int a, b;

	// 重载小于号
	bool operator< (const Rec2& t) const
	{
		return a < t.a;
	}
};

struct Rec3
{
	int a, b;

	// 重载大于号
	bool operator> (const Rec3& t) const
	{
		return a > t.a;
	}
};

int main()
{
    // 普通队列指的就是循环队列
	// 循环队列的性质是:先进先出
	queue<int> a;
	queue<double> b;
	queue<Rec1> c;

	// 优先队列默认定义是大根堆,性质是:优先往外弹出所有数中的最大值
	priority_queue<int> d;// 默认为大根堆
	priority_queue<int, vector<int>, greater<int>> e;// 这个则为小根堆,性质是:优先往外弹出所有数中的最小值
	
	priority_queue<pair<int, int>> f;// pair是一个二元组

	priority_queue<Rec2> g;// 这个为大根堆。这个Rec2结构体必须重载小于号
	priority_queue<Rec3, vector<Rec3>, greater<Rec3>> h;// 这个为小根堆。这个Rec3结构体必须重载大于号

	g.push({ 1, 2 });
	h.push({ 1, 2 });

	return 0;
}
#include <iostream>
#include <queue>

using namespace std;

int main()
{
	queue<int> a;

	a.push(1);// 在队尾插入一个元素
	a.push(2);
	a.push(3);
	a.push(4);
	a.pop();// 弹出队头元素
	// 返回队头元素的值
	cout << "队头元素的值:" << a.front() << endl;// 2
	// 返回队尾元素的值
	cout << "队尾元素的值:" << a.back() << endl;// 4

	priority_queue<int> b;// 大根堆

	b.push(5);// 插入一个元素,插入的位置会自动根据情况调整
	b.push(6);
	b.push(7);
	cout << b.top() << endl;// 返回最大值
	b.pop();// 删除最大值
	cout << b.top() << endl;

	a = queue<int>();// 这就相当于重新初始化了一个队列,清空了队列

	return 0;
}

stack

#include <iostream>
#include <stack>

using namespace std;

int main()
{
	stack<int> stk;

	stk.push(1);// 栈顶插入一个元素
	stk.top();// 返回栈顶元素的值
	stk.pop();// 删除栈顶元素

	return 0;
}

deque(双端队列)

  • deque在队头和队尾,插入或删除的时间复杂度都是:O(1)
#include <iostream>
#include <deque>

using namespace std;

int main()
{
	deque<int> a;

	a.begin();
	a.end();

	a.front();
	a.back();
	
	a.push_back(1);
	a.push_front(2);

	cout << "=========" << endl;
	a[0];// deque支持随机访问一个元素

	a.pop_back();
	a.pop_front();

	a.clear();// 清空元素

	return 0;
}

set

#include <iostream>
#include <set>

using namespace std;

struct Rec
{
	int x, y;

	// 重载小于号
	bool operator< (const Rec& t) const
	{
		return x < t.x;
	}
};

int main()
{
	// set本质上是用来动态维护一个有序的集合。set和multiset底层实现都是一棵红黑树。

	set<int> a;// 元素不能重复
	multiset<int> b;// 元素可以重复。multiset的函数和set的函数一样
	set<Rec> c;// 这个Rec结构体必须重载小于号
	
	// 迭代器
	set<int>::iterator it = a.begin();
	it++;// 这里的 it++ 表示的是在有序的集合里的下一个元素
	a.end();

	a.insert(2);// 插入一个值为2的元素
	a.find(2);// 这个函数会返回set中元素值等于2的迭代器。如果没有找到值为2的元素,则会返回相当于 a.end() 的值
	// if (a.find(2) == a.end()) {}// 这个可以判断2在a中是否存在

	a.lower_bound(2);// 返回 大于等于 2的最小的元素的迭代器
	a.upper_bound(2);// 返回 大于 2的最小的元素的迭代器

	a.erase(it);// 从a中删除迭代器it指向的元素
	a.erase(2);// 从a中删除等于2的元素

	a.count(2);// 返回集合a中元素值等于2的个数。这里为set集合,所以结果要么是0,要么是1

	return 0;
}

map

#include <iostream>
#include <map>
#include <vector>

using namespace std;

int main()
{
	// multimap基本不会用到
	// multimap<string, int> temp;
	
	// map是常用的
	map<string, int> a;

	a["yxc"] = 2;
	a["cgw"] = 99;

	cout << a["cgw"] << endl;

	map<string, vector<int>> b;

	b.insert({ "hhh", {} });// 插入一个map元素
	b["yxc"] = vector<int>({ 1, 2, 3, 4 });
	b["jjj"] = { 1, 2, 3 };
	b["kkk"] = { 4, 5, 6 };	

	cout << b["kkk"].size() << endl;
	cout << b["kkk"][0] << endl;// 4
	cout << b["kkk"][1] << endl;// 5
	cout << b["kkk"][2] << endl;// 6

	cout << (b.find("cgw") == b.end()) << endl;

	return 0;
}

unordered_set、unordered_map

#include <iostream>
#include <unordered_set>
#include <unordered_map>

using namespace std;

int main()
{
	// 无序的set
	// 没有lower_bound()、upper_bound()函数,其它的函数set有的,它也有,但是时间复杂度是:O(1),效率比set快
	// 底层实现是:哈希表
	unordered_set<int> a;// 元素不可以重复
	unordered_multiset<int> b;// 元素可以重复

	// 和map完全一样,好处就是函数的时间复杂度对比map为O(1),但是unordered_map不支持二分
	unordered_map<int, int> c;
	unordered_multimap<int, int> d;// 不常用

	return 0;
}

bitset

#include <iostream>
#include <bitset>

using namespace std;

int main()
{
	// 一般进行位运算就会用到bitset
	bitset<1000> a;// 定义了一个长度为1000位的0或1的串

	a[0] = 1;
	a[1] = 2;// 这里a[1]的值存的还是1,因为bitset是只能存0或者1

	cout << a[0] << endl;// 1
	cout << a[1] << endl;// 1
	cout << a[2] << endl;// 没有赋过值的则为0

	cout << a.count() << endl;// 返回a里面1的个数

	a.set(3);
	cout << a[3] << endl;// 可以把a下标为3的赋值为1

	a.reset(3);
	cout << a[3] << endl;// 可以把a下标为3的赋值为0

	return 0;
}

pair

#include <iostream>
#include <bitset>

using namespace std;

int main()
{
	pair<int, string> a, b;

	a = { 3, "yxc" };

	cout << a.first << ' ' << a.second << endl;

	a = make_pair(4, "abc");// 如果是在C++9中,只能这样赋值

	cout << a.first << ' ' << a.second << endl;

	// if (a > b) {}// pair是支持比较运算的,pair是双关键字进行比较,先比较first,再比较second

	return 0;
}

位运算

  • 与:& AND

  • 或:| OR

  • 非:~ NOT

  • 异或:^ XOR

  • 右移:>>

  • 左移:<<

#include <iostream>

using namespace std;

int main()
{
	int a = 3, b = 6;
	
	cout << (a ^ b) << endl;// 这里要加上括号,因为会有优先级的问题

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a = 13;
	// 位数:		第3位 第2位 第1位 第0位
	// 13的二进制:    1     1    0     1

	// 求出a的二进制中第2位的数是多少
	cout << (a >> 2 & 1) << endl;// 1

	// 把a的二进制的每个数都遍历出来
	for (int i = 3; i >= 0; i--)
		cout << (a >> i & 1) << ' ';

	return 0;
}
#include <iostream>

using namespace std;

int main()
{
	int a = 2312321;

	// 在计算机中 -a 等于 (~a + 1)
	int b = -a;
	int c = (~a + 1);

	cout << b << ' ' << c << endl;// -2312321 -2312321

	/*
		lowbit(x)这个函数是我们自定义的,能够实现返回 x 的最后一位1及其后面的所有0
		
		下面这两种写法是一模一样的:
		定义一个 lowbit(a) 函数,直接返回 a & -a 的值
		定义一个 lowbit(a) 函数,直接返回 a & (~a + 1) 的值
	*/

	return 0;
}

常用库函数

  • C++帮我们实现好了很多有用的函数,我们要避免重复造轮子

reverse

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
	// vector<int> a({ 1, 2, 3, 4, 5 });
	// reverse(a.begin(), a.end());// 反转函数

	int a[] = { 1, 2, 3, 4, 5 };
	// reverse(a, a + sizeof(a) / sizeof(int));
	reverse(a, a + 5);

	for (int x : a)
		cout << x << ' ';

	return 0;
}

unique

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
	// unique是去重函数,用这个函数时,一定要保证相同的数是紧挨在一起的
	
	// int a[] = { 1, 1, 2, 2, 3, 3, 4 };
	/*
		unique(x, y)
		第一个参数为开始位置,第二个参数为最后一个数的位置的下一个位置
		函数的返回值是去重后的最后一个数的位置的下一个位置
	*/
	// int m = unique(a, a + 7) - a;
	// cout << m << endl;// m的值为去重后的数组a中不重复的数的个数
	
	// vector<int> a({ 1, 1, 2, 2, 3, 3, 4 });
	// int m = unique(a.begin(), a.end()) - a.begin();
	// cout << m << endl;

	/*
		for (int i = 0; i < m; i++)
			cout << a[i] << ' ';// 1 2 3 4
	*/

	vector<int> a({ 1, 1, 2, 2, 3, 3, 4 });
	// 把 去重后的数组a的最后一个元素的下一个位置 到 去重前的数组a的最后一个元素的下一个位置 的 指针所指向的位置的元素全部删除。
	// erase函数的参数也是符合左闭右开的特性
	a.erase(unique(a.begin(), a.end()), a.end());
	for (int x : a)
		cout << x << ' ';// 1 2 3 4

	return 0;
}

random_shuffle

#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>

using namespace std;

int main()
{
	vector<int> a({ 1, 2, 3, 4, 5 });

	// time(0) 返回值为1970年1月1号到当下时间的毫秒数
	srand(time(0));// 把时间当做随机种子

	// 如果随机种子不变的话,则每次打乱的顺序都是一样的
	random_shuffle(a.begin(), a.end());// 把容器中元素的顺序打乱

	for (int x : a)
		cout << x << ' ';

	return 0;
}

sort

#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>

using namespace std;

bool cmp(int a, int b)// a是否应该排在b的前面
{
	return a < b;
}

int main()
{
	vector<int> a({ 1, 2, 3, 4, 5 });
	srand(time(0));
	random_shuffle(a.begin(), a.end());
	for (int x : a)
		cout << x << ' ';
	cout << endl;

	// sort(a.begin(), a.end());// 能自动把a中的元素进行从小到大排序
	// sort(a.begin(), a.end(), greater<int>());// 能自动把a中的元素进行从大到小排序
	sort(a.begin(), a.end(), cmp);// cmp是我们自定义的一个函数

	for (int x : a)
		cout << x << ' ';
	cout << endl;

	return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <ctime>

using namespace std;

struct Rec
{
	int x, y;

	//bool operator< (const Rec& t) const
	//{
	//	return x < t.x;
	//}
}a[5];

bool cmp(Rec a, Rec b)// 这个函数中的参数的结构体类型的定义,一定要写在函数的前面
{
	return a.x < b.x;
}

int main()
{
	for (int i = 0; i < 5; i++)
	{
		a[i].x = -i;
		a[i].y = i;
	}

	for (int i = 0; i < 5; i++)
		printf("(%d,%d) ", a[i].x, a[i].y);
	printf("\n");

	sort(a, a + 5, cmp);
	// sort(a, a + 5);// 这种写法的话结构体必须重载小于号或者重载大于号

	for (int i = 0; i < 5; i++)
		printf("(%d,%d) ", a[i].x, a[i].y);
	printf("\n");

	return 0;
}

lower_bound、upper_bound

  • 使用 lower_bound、upper_bound 函数时,必须保证元素是按顺序从小到大排好的
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	int a[] = { 1, 2, 4, 5, 6 };

	// 返回数组中大于等于4的第一个元素的下标
	int* p = lower_bound(a, a + 5, 4);
	cout << p - a << ":" << *p << endl;// 2:4
	
	// 返回数组中大于4的第一个元素的下标
	p = upper_bound(a, a + 5, 4);
	cout << p - a << ":" << *p << endl;// 3:5

	return 0;
}

习题

数字在排序数组中出现的次数

class Solution {
public:
    int getNumberOfK(vector<int>& nums , int k) {
        int cnt = 0;
        for (int x : nums)
            if (x == k)
                cnt++;
        return cnt;
    }
};

0到n-1中缺失的数字

class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        if (nums.empty())
            return 0;
        int size = nums.size();
        int key = 0;
        for (int x : nums)
        {
            if (x != key)
                return key;
            key++;
            if (key == size)
                return key;
        }
    }
};
class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        unordered_set<int> a;
        for (int i = 0; i <= nums.size(); i++)
            a.insert(i);
        for (int x : nums)
            a.erase(x);
        return *a.begin();
    }
};

调整数组顺序使奇数位于偶数前面

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        vector<int> odd;
        vector<int> even;
        for (int x : array)
        {
            if (x % 2)
                odd.push_back(x);
            else
                even.push_back(x);
        }
        array.clear();
        for (int x : odd)
            array.push_back(x);
        for (int x : even)
            array.push_back(x);
        return;
    }
};

从尾到头打印链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> printListReversingly(ListNode* head) {
        vector<int> a;
        for (ListNode* i = head; i != NULL; i = i->next)
            a.push_back(i->val);
        reverse(a.begin(), a.end());
        return a;
    }
};

用两个栈实现队列

class MyQueue {
public:
    stack<int> a;
    stack<int> b;
    /** Initialize your data structure here. */
    MyQueue() {
        
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        a.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        while (!a.empty())
        {
            b.push(a.top());
            a.pop();
        }
        int temp = b.top();
        b.pop();
        while (!b.empty())
        {
            a.push(b.top());
            b.pop();
        }
        return temp;
    }
    
    /** Get the front element. */
    int peek() {
        while (!a.empty())
        {
            b.push(a.top());
            a.pop();
        }
        int temp = b.top();
        while (!b.empty())
        {
            a.push(b.top());
            b.pop();
        }
        return temp;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        if (a.empty())
            return true;
        else 
            return false;
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * bool param_4 = obj.empty();
 */

最小的k个数

class Solution {
public:
    vector<int> getLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> res;
        sort(input.begin(), input.end());
        for (int i = 0; i < k; i++)
            res.push_back(input[i]);
        return res;
    }
};

和为S的两个数字

class Solution {
public:
    vector<int> findNumbersWithSum(vector<int>& nums, int target) {
        vector<int> res;
        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size(); i++)
        {
            int temp = target - nums[i];
            for (int j = i + 1; j < nums.size(); j++)
            {
                if (temp == nums[j])
                {
                    res.push_back(nums[i]);
                    res.push_back(nums[j]);
                    return res;
                }
            }
        }
    }
};

数字排列

class Solution {
public:
    vector<vector<int>> permutation(vector<int>& nums) {
        vector<int> temp;
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        map<int, bool> p;
        for (int i = 0; i < nums.size(); i++)
            p[i] = false;
        func(p, temp, nums, res);
        sort(res.begin(), res.end());
        res.erase(unique(res.begin(), res.end()), res.end());
        return res;
    }
    
    void func(map<int, bool>& p, vector<int>& temp, vector<int> nums, vector<vector<int>>& res)
    {
        if (temp.size() == nums.size())
        {
            res.push_back(temp);
            return;
        }
        for (int i = 0; i < nums.size(); i++)
        {
            if (!p[i])
            {
                temp.push_back(nums[i]);
                p[i] = true;
                func(p, temp, nums, res);
                temp.pop_back();
                p[i] = false;
            }
        }
        return;
    }
};
class Solution {
public:
    vector<vector<int>> permutation(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        do
            res.push_back(nums);
        while (next_permutation(nums.begin(), nums.end()));// 可以使用前人帮我们写好的函数
        /*
            next_permutation
            函数的返回值为true:
                则表示当前序列不是最大的序列,然后帮助我们排列出比当前nums序列更大的下一个序列
            函数的返回值为false:
                则表示当前序列已经是最大的序列
        */
        return res;
    }
};

二进制中1的个数

class Solution {
public:
    int NumberOf1(int n) {
        int res = 0;
        for (int i = 0; i < 32; i++)
            if (n >> i & 1)
                res++;
        return res;
    }
};
class Solution {
public:
    int NumberOf1(int n) {
        int res = 0;
        while (n)
        {
            n -= n & (~n + 1);
            // n & (~n + 1) 这个相当于得到二进制n的最后一个1以及后面的所有0
            res++;
        }
        return res;
    }
};

三元组排序

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

struct Rec
{
    int a;
    double b;
    string c;
    
    Rec(int _a, double _b, string _c) : a(_a), b(_b), c(_c) {}
};

bool cmp(Rec x, Rec y)
{
    return x.a < y.a;
}

int main()
{
    int n;
    cin >> n;
    vector<Rec> res;
    while (n--)
    {
        int a;
        double b;
        string c;
        cin >> a >> b >> c;
        Rec rec(a, b, c);
        res.push_back(rec);
    }
    sort(res.begin(), res.end(), cmp);
    for (Rec temp : res)
        printf("%d %.2lf %s\n", temp.a, temp.b, temp.c.c_str());
    return 0;
}
  • 33
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值