目录
回文数
方法一:正常数据翻转
#include<bits/stdc++.h>
using namespace std;
int main() {
int x = 0;
ios::sync_with_stdio(false);
cin >> x;
int a = x; //存储数据,为后期进行对比
int b = 0; //反转后的数据
while (a != 0) {
b = b * 10 + a % 10;
a /= 10;
}
if (x == b) {
cout << "是回文数!" << endl;
cout << "x=" << x << endl;
cout << "b=" << b << endl;
}
else {
cout << "不是回文数!" << endl;
cout << "x=" << x << endl;
cout << "b=" << b << endl;
}
return 0;
}
方法二:利用字符串进行翻转
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
int x;
cin >> x;
string s = to_string(x); //将x转化为字符串
string s1 = s;
reverse(s1.begin(), s1.end()); //字符串进行翻转
if (s == s1) {
cout << "是回文数!" << endl;
cout << "s1=" << s1 << endl;
cout << "s=" << s << endl;
}
else {
cout << "不是回文数!" << endl;
cout << "s1=" << s1 << endl;
cout << "s=" << s << endl;
}
return 0;
}
题目练习:
约瑟夫环
方法一:使用队列
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
queue<int>q;
int main()
{
int n,k,m;
cin>>n>>k>>m;
int t=k%n; //算出第一个位置
for(int i=t;i<=n;++i) q.push(i); //[t,n]进队列
for(int i=1;i<t;++i) q.push(i); //[1,t)进队列
while(!q.empty()){
for(int i=1;i<m;++i){ //计数 [1,m)的放到后面
q.push(q.front());
q.pop();
}
cout<<q.front()<<endl; //输出第m个位置的数
q.pop();
}
return 0;
}
练习题目:
其他总结
vector<>的遍历输出vector遍历:
假如:vector<int> line={1,2,3,4,5,6,7,8,9};
方法一:for循环迭代器输出
for(vetcor<int>::const_iterator it=line.begin();it!=line.end();it++){
cout<<(*it)<<endl;
}
或
for(auto it=line.begin();it!=line.end();it++){
cout<<(*it)<<endl;
}
方法二: for_each()函数
template <typename T>
void printer(const T& line) {
cout << line;
cout << endl;
}
void showvec(const vector<int>& line) {
for_each(line.cbegin(), line.cend(), printer<int>);
}
方法三:for区间遍历:
for (auto lin : line) {
cout << lin;
}
数字和字符的转化:
字符变成数字:
- ’0’==49;
- ’a’==0;
a+’0’==145;
a+’a’==194;
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str = "abc";
int shu[10];
memset(shu, 0, sizeof(shu));
for (int i = 0; i < str.length(); i++)
{
shu[i] = str[i] - '0'; // 49 50 51
shu[i] = str[i] - 'a'; // 0 1 2
cout << shu[i] << " ";
}
cout << endl;
for (int i = 0; i < str.length(); i++)
{
char k = shu[i]+ '0'; // a b c
char k = shu[i]+ 'a'; // a b c
cout << k << " ";
}
cout << endl;
return 0;
}
最短路径算法:(Floyd算法)
template<typename T>
class FloydAlgorithm :public ShortestPathAlgorithm<T>
{
void solve(std::vector<std::vector<T>>& roadArray)
{
int length = roadArray.size();
for (int k = 0; k < length; k++)
{
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
if (roadArray[i][k] + roadArray[k][j] < roadArray[i][j])
{
roadArray[i][j] = roadArray[i][k] + roadArray[k][j];
}
}
}
}
}
};
数字和字符相互转化:
/* string -> int*/
void sti(string& s, int& x) {
x = atoi(s.c_str());
}
/* int->string */
void its(string& s, int& x) {
stringstream ss;
ss << x;
s = ss.str();
}
判断是否是反转数:
bool rev(int n) {
stringstream ss;
ss << n;
string s = ss.str();
string t = s;
reverse(s.begin(), s.end());
if (s == t) return true;
return false;
}
数字转化字符串进行反转:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
stringstream ss;
ss << n;
string s = ss.str();
reverse(s.begin(), s.end());
cout << n << endl;
cout << s << endl;
//cout << ss << endl;
return 0;
}
/*
输出结果是:
123456
123456
654321
*/
大小写转化:
/*小写字母=大写字母+32,则大写字母=小写字母-32*/
#include<bits/stdc++.h>
using namespace std;
int main() {
char s;
cin >> s;
//cout << char(int(s) - 32) << endl; //小写变成大写: a->A;
cout << char(int(s) + 32) << endl; //大写变成小写: A->a
return 0;
}
A-65 a-97
## 头文件 <cmath>
# 向上取整 ceil()
ceil(1.5)=2
ceil(0.5)=1
ceil(1)=1
# 向下取整 floor()
ceil(1.5)=1
ceil(0.5)=0
ceil(1)=1
判断是否是闰年:
bool run(int y) {
if (y% 400 == 0 || (y % 100 != 0 && y % 4 == 0)) return true;
return false;
}
计算星期几:彩基姆拉尔森计算公式
星期为w,年份为y,月份为m,日期为d。
w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7
计算后把w+1就是真正的星期几了
注意:每年的1.2月份要当成上一年的13.14月计算,上述的除法均为整数。
判断月份:
day[31]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //2月份独自判断;
if(y%400==0||(y%100!=0 && y %4==0)) day[2]=29;
else day[2]=28;
31天的有:1,3,5,7,8,10,12;
30天的有:4,6,9,11;
2月份独自判断;
判断是否是质数(素数):
bool zhi(int k) {
for (int i = 2; i <= sqrt(k)+0.5; ++i) {
if (k % i == 0)
return false;
}
return true;
}
26个字符串小写:从下标0开始Z-Y
char str[26] = { 'Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y' };
26个字符串小写:从下标0开始z-y
char str[26] = { 'z,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y' };
最大公约数:
int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a % b);
}
最小公倍数:
int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a % b);
}
int lcm(int a, int b) { //最小公倍数
return a * b /gcd(a, b);
}
二进制 八进制 十六进制 :
#include<bits/stdc++.h>
using namespace std;
int main() {
int a = 20;
printf("%d %o %x\n", a, a, a); //20 24 14 十进制%d 八进制%o 十六进制%x
return 0;
}
二进制输出:
itoa(x, s, 2);
printf("%s\n",s);
N进制输出:
itoa(x, s, N);
printf("%s\n",s);
用法:
#include<bits/stdc++.h>
using namespace std;
int main() {
int x = 80;
char s[10];
itoa(x, s, 10);
cout << s << endl;
return 0;
}
求多个数乘积之后0的个数方法:
一.所谓正统思想,应该是看这些数当中2与5有多少对,因为乘法当中的10是由2×5得出的。将每一个数的因数中的2的个数统计出来,5同理,然后取两者的最小值即为对数。
“尺取法”:
(1)啥情况适合用尺取法:涉及“(寻找任一个)区间”。
(2)想清楚两个点:①针对题意,怎么找到这个区间,即这个区间应满足怎样的条件。②关于start和end标识,什么时候start++,什么时候end++,什么时候应该跳出循环。anyway,要好好分析题意,结合题意设计。
求1-n个数 至少需要几个数做加减能全部得出:
例如:
1 1个(1:1)
7 3 个(1,4,6:1,6-4,6-4+1,4,6-1,6,6+1)
a +1<=a<=个
大数四则运算输入输出:
void input(vector<int>& v, string& a) {
for (int i = a.size() - 1; i >= 0; i--) v.push_back(a[i] - '0');
}
void output(vector<int>& v) {
for (int i = v.size() - 1; i >= 0; i--)cout << v[i];
}
大数相加算法:
/*大数相加*/
#include<iostream>
#include<vector>
using namespace std;
string a, b;
vector<int> add(vector<int>& A, vector<int>& B)
{
for (int i = a.size() - 1; i >= 0; i--)
A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--)
B.push_back(b[i] - '0');
int t = 0;
vector<int> C;
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size())
t += A[i];
if (i < B.size())
t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t)
C.push_back(t);
return C;
}
int main()
{
vector<int> A, B, C;
cin >> a >> b;
C = add(A, B);
for (int i = C.size() - 1; i >= 0; i--)
cout << C[i];
cout << endl;
return 0;
}
大数相减算法:
#include<bits/stdc++.h>
using namespace std;
bool cmp_s(vector<int>& vec1, vector<int>& vec2)
{
if (vec1.size() != vec2.size()) return vec1.size() >= vec2.size();
for (int i = vec1.size() - 1; i >= 0; i--)
{
if (vec1[i] != vec2[i])return vec1[i] > vec2[i];
}
return true;
}
//c=vec1-vec2
vector<int> sub_s(vector<int>& vec1, vector<int>& vec2)
{
vector<int>c;
for (int i = 0, t = 0; i < vec1.size(); i++)
{
t = vec1[i] - t;
if (i < vec2.size()) t = t - vec2[i];
c.push_back((t + 10) % 10);
if (t < 0)
{
t = 1;
}
else {
t = 0;
}
}
//去掉前导0
while (c.size() > 1 && c.back() == 0)c.pop_back();
return c;
}
int main()
{
string a, b;
cin >> a >> b;
vector<int>vec1, vec2;
for (int i = a.size() - 1; i >= 0; i--)vec1.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--)vec2.push_back(b[i] - '0');
if (cmp_s(vec1, vec2))
{
auto c = sub_s(vec1, vec2);
for (int i = c.size() - 1; i >= 0; i--)printf("%d", c[i]);
}
else {
auto c = sub_s(vec2, vec1);
cout << "-";
for (int i = c.size() - 1; i >= 0; i--)printf("%d", c[i]);
}
}
大数相乘算法:
/*大数相乘 a>=0 && b>=0*/
#include<bits/stdc++.h>
using namespace std;
vector<int> mul_s(vector<int>& vec1, int& b)
{
vector<int>c;
int t = 0;
for (int i = 0; i < vec1.size(); i++)
{
t = vec1[i] * b + t;
c.push_back(t % 10);
t /= 10;
}
while (t)
{
c.push_back(t % 10);
t /= 10;
}
return c;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> vec1;
for (int i = a.size() - 1; i >= 0; i--) vec1.push_back(a[i] - '0');
auto x = mul_s(vec1, b);
for (int i = x.size() - 1; i >= 0; i--) cout << x[i];
}
大数相除算法:
/*大数相除 vec>=0 b>=0 */
#include<bits/stdc++.h>
using namespace std;
vector<int> div_s(vector<int>& vec, int b, int& r)
{
vector<int> c;//商
for (int i = vec.size() - 1; i >= 0; i--)
{
r = r * 10 + vec[i];//余数*10+下一位
c.push_back(r / b);
r %= b;
}
//for(int i=0;i<=vec.size()-1;i++)cout<<vec[i];
reverse(c.begin(), c.end());
while (c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> vec;//被除数
for (int i = a.size() - 1; i >= 0; i--) vec.push_back(a[i] - '0');
int r = 0;//商
auto c = div_s(vec, b, r);
for (int i = c.size() - 1; i >= 0; i--)cout << c[i];
cout << endl << r;
}
前N向求和的树状
/*前N向求和的树状*/
#include<bits/stdc++.h>
using namespace std;
int lowbit(int n) {
return n - (n & (n - 1));
}
void updata(int n, int i, int v, int c[]){
for (int k = i; k <= n; k += lowbit(k)) {
c[k] += v;
}
}
int getsum(int c[], int i) {
int sum = 0;
for (int k = i; k >= 1; k-=lowbit(k)) {
sum += c[k];
}
return sum;
}
int main() {
int arr[] = { 11,2,3,4,5,6,7,8,9 };
int c[9];
memset(c, 0, sizeof(c));
for (int i = 0; i < 8; ++i) {
updata(9, i + 1, arr[i], c);
}
cout << getsum(c,1) << endl; //11
cout << getsum(c, 5) -getsum(c,4)<< endl; //5
cout << getsum(c, 2) - getsum(c, 1) << endl; //2
return 0;
}
/*
------------
输出结果是:
11
5
2
----------
*/
哈夫曼距离:
D1(x1,y1)和D2(x2,y2)的距离计算公式
D(x,y)=|x1-x2|+|y1-y2|