十进制转R进制
cpp
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string tentoR(int x, int r) {
if (x == 0) return "0"; // 如果x为0,直接返回"0"
string s;
while (x) {
int num = x % r;
if (num >= 10) s += 'A' + (num - 10); // 处理10及以上的数字转为字母
else s += num + '0'; // 处理0-9的数字
x /= r;
}
reverse(s.begin(), s.end()); // 反转字符串得到正确的顺序
return s;
}
int main() {
int n, r;
cin >> n >> r;
cout << tentoR(n, r);
return 0;
}
计算一个数转为二进制后有几个1
cpp
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int calebinone(int x)
{
int cnt = 0;
while (x)
{
cnt++;
x &= x - 1;//每次将最后一个1变为0
}
return cnt;
}
int main()
{
int n;
cin >> n;
cout << calebinone(n);
}
异或(^)相同为0,不同为1
最大公约数和最小公倍数(递归版本)
cpp
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int gcd(int a, int b) // 最大公约数
{
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b) // 最小公倍数
{
return a / gcd(a, b) * b;
}
int main()
{
int a, b;
cin >> a >> b;
cout << "最大公约数是:" << gcd(a, b) << endl;
cout << "最小公倍数是:" << lcm(a, b) << endl;
return 0;
}
日期(闰年)
显示某一年的日历
cpp
#include<iostream>
using namespace std;
int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
// 检查是否为闰年
bool check(int year) {
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return true;
return false;
}
int main() {
int y;
cin >> y;
// 根据年份调整二月天数
if(check(y))
days[2] = 29;
else
days[2] = 28; // 确保处理多个年份时对于非闰年,二月的天数正确设置为28天
for(int i = 1; i <= 12; i++) { // 十二个月
for(int j = 1; j <= days[i]; j++)
cout << y << "年" << i << "月" << j << "日" << endl;
}
return 0;
}
判断素数(试除法&埃氏筛)
cpp
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
//单个素数判定--试除法 O(sqrt(n))
bool isprime(int n)
{
if(n<=1) return false;
int sqrtn=sqrt(n);
for(int i=2;i<=sqrtn;i++)
{
if(n%i==0)
return false;
}
return true;
}
//多个素数判定--埃氏筛O(nloglogn)
//找到一个素数把他的倍数全筛出
#include<vector>
const int N=1e6+10;
bool vis[N];//标记一个数是否为素数
vector<int> prime;//素数表
void E_sieve()
{
vis[0]=vis[1]=1;//提前处理1和2为非素数
for(int i=2;i<=N-10;i++)
{
if(!vis[i])//是素数
{
for(int j=2*i;j<=N-10;j+=i)
{
vis[j]=1;
}
}
}
}
signed main()
{
int n;
cin>>n;
cout<<"素数有:"<<endl;
E_sieve();
for(int i=2;i<=n;i++)
{
// if(isprime(i))
// cout<<i<<" ";
if(!vis[i])
cout<<i<<" ";
}
for(auto it:prime) {
if(it>n) break;
cout<<it<<" ";
}
return 0;
}
计算a的b次方的模运算
cpp
#include<iostream>
using namespace std;
int main()
{
int a,b,mod;
cin>>a>>b>>mod;
int ans=1;
for(int i=1;i<=b;i++)
{
ans*=a%mod;
ans%=mod;
}
cout<<ans;
return 0;
}
前缀和
一维前缀和查询区间和
cpp
//一维前缀和
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N],ps[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ps[i]=ps[i-1]+a[i];
}
int m;//查询m次区间和
cin>>m;
while(m--)
{
int l,r;
cin>>l>>r;
cout<<ps[r]-ps[l-1]<<endl;
}
return 0;
}
二维前缀和查询矩阵和(最大子矩阵问题)
cpp
#include<iostream>
using namespace std;
const int N=1e3+10;
int a[N][N],ps[N][N];
int main(){
int n; cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
ps[i][j]=ps[i-1][j]+ps[i][j-1]-ps[i-1][j-1]+a[i][j];
}
}
int m; cin>>m;
while(m--){
int r1,c1,r2,c2; cin>>r1>>c1>>r2>>c2;
cout<<ps[r2][c2]-ps[r1-1][c2]-ps[r2][c1-1]+ps[r1-1][c1-1]<<endl;
}
return 0;
}
搜索与回溯
全排列模板
cpp
#include<iostream>
using namespace std;
string s;
const int N=1e2+10;
char ch[N];
bool vis[N];
void dfs(int dep){
//5.终止条件
if(dep==s.size()+1){
for(int i=1;i<dep;i++){
cout<<ch[i];
} cout<<endl;
return ;
}
//1.枚举搜索方案
for(int i=0;i<s.size();i++){
//2.标记-防止重复搜索
if(!vis[i]){
//3.搜索
vis[i]=1;//标记
ch[dep]=s[i];//记录第dep层搜了谁
dfs(dep+1);//进入下一层继续搜索
//4.回溯
vis[i]=0;
}
}
}
int main(){
cin>>s; //abc
dfs(1);
return 0;
}
迷宫搜索-bfs求无权图最短路
cpp
#include<iostream>
#include<queue>
using namespace std;
const int N=1e3+10;
char g[N][N];//迷宫数组
bool vis[N][N];//标记数组
int n,m,sx,sy,tx,ty,ans=-1;
//方向数组
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
struct point{int x,y,step;};
void bfs(point s){
queue<point> q;
//1.起点入队+标记
q.push(s); vis[s.x][s.y]=1;
//2.循环广搜
while(!q.empty()){
//3.取出当前正在搜索的点
point cur=q.front(); q.pop();
//判断是否是终点
if(cur.x==tx&&cur.y==ty){
ans=cur.step;
return ;
}
//4.沿着邻接点继续搜索
for(int i=0;i<4;i++){
int bx=cur.x+dx[i],by=cur.y+dy[i];
if(bx<1||bx>n||by<1||by>m) continue;
if(g[bx][by]=='*') continue;
if(vis[bx][by]) continue;
q.push({bx,by,cur.step+1});
vis[bx][by]=1;
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>g[i][j];
cin>>sx>>sy>>tx>>ty;
bfs({sx,sy,0});
cout<<ans<<endl;
return 0;
}
***图论- 有权图多源最短路Floyd
cpp
#include<iostream>
#include<climits>
#include<algorithm>
using namespace std;
const int N = 3e3 + 10, INF = INT_MAX;
int g[N][N];//邻接矩阵
bool vis[N];//标记数组
int mindis[N][N];//含义:mindis[i][j]顶点i到顶点j的最短距离
int n = 2021, s = 1;
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
//时间复杂度O(n^3)
void floyd() {
//枚举跳板(中转点)
for (int k = 1; k <= n; k++) {
//枚举任意两点
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (mindis[i][k] != INF && mindis[k][j] != INF) {
if (mindis[i][k] + mindis[k][j] < mindis[i][j]) {
mindis[i][j] = mindis[i][k] + mindis[k][j];
}
}
}
}
}
}
int main() {
fill(mindis[0], mindis[0] + N * N, INF);
for (int i = 1; i <= n; i++) {
for (int j = max(i - 21, 1); j <= min(i + 21, 2021); j++) {
if (i != j) mindis[i][j] = mindis[j][i] = lcm(i, j);
}
}
//floyd();
//cout << mindis[1][n] << endl;
cout << 10266837 << endl;
return 0;
}
DP
最长上升子序列
cpp
#include<iostream>
using namespace std;
//最长上升子序列-LIS
//1.状态 dp[i] 以第i个元素作为结尾的最长上升子序列的长度
//2.状态转移方程 if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1)
//a 1 2 3 4 5 6 7
// 1 7 3 5 9 4 8
//dp 1 2 3 4 5 6 7
// 1 2 2 3 4 3 4
const int N = 1e3 + 10;
int a[N], dp[N];
int main() {
int n; cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
dp[i] = 1;//边界,每一个元素自身构成最长上升
}
int mx = 1;
for (int i = 2; i <= n; i++) {
//使用j遍历第i个元素之前的所有元素
for (int j = 1; j < i; j++) {
//找到a[j]和a[i]构成上升的情况
if (a[j] < a[i]) dp[i] = max(dp[i], dp[j] + 1);
}
mx = max(mx, dp[i]);
}
cout << mx << endl;
return 0;
}
STL
List链表(大量的对头尾进行操作时使用)
cpp
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<int>ls;
if (!ls.empty())
{
ls.pop_back();//移除列表的最后一个元素
ls.pop_front();//移除列表的第一个元素
}
ls.push_back(10);//列表的末尾添加一个元素
ls.push_front(5);//列表的开头添加一个元素
// 打印列表中的所有元素
for (int elem : ls) {
cout << elem << " ";
}
cout << endl;
return 0;
}
String字符串
cpp
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string s1, s2;
getline(cin, s1);
getline(cin, s2);
s1 += s2; // 拼接
if (s1 == s2) { // 比较
cout << "s1 and s2 are equal." << endl;
}
s1 = s2; // 拷贝
//查找子串
if(s1.find(s2)!=-1){
cout<<s2<<" is substr of "<<s1<<endl;
}
while((pos=s1.find(s2,pos))!=-1){
pos++;
cnt++;//统计子串数量
}
reverse(s1.begin(), s1.end()); // 反转s1
// 类型转换示例
string numStr = to_string(123); // 整数转字符串
int num = stoi(s2); // 字符串转整数
double dnum = stod(s2); // 字符串转双精度浮点数
long lnum = stol(s2); // 字符串转长整型
return 0;
}
stack栈
cpp
#include<iostream>
#include<stack>
using namespace std;
int main(){
stack<int> st;
int n; cin>>n;
for(int i=1;i<=n;i++){
int x; cin>>x;
st.push(x);
}
while(!st.empty()){
cout<<st.top()<<" ";
st.pop();
}
return 0;
}
queue队列
cpp
#include<iostream>
#include<queue>
using namespace std;
int main(){
queue<int> q;
int n; cin>>n;
for(int i=1;i<=n;i++){
int x; cin>>x;
q.push(x);
}
while(!q.empty()){
//注意是front()
cout<<q.front()<<" ";
q.pop();
}
return 0;
}
set(去重++排序)
cpp
#include<iostream>
#include<set>
using namespace std;
int main(){
set<int> s;
int n; cin>>n;
for(int i=1;i<=n;i++){
int x; cin>>x;
//插入元素用insert
s.insert(x);//底层是红黑树 O(logn)
}
for(auto it:s) cout<<it<<" ";
return 0;
}
map(针对key去重+排序 )
cpp
#include<iostream>
#include<map>
using namespace std;
//STL-map
int main(){
map<int,string> mp;
int n; cin>>n;
for(int i=1;i<=n;i++){
int id; string book;
cin>>id>>book;
//map.insert({id,book});
mp[id]=book;
}
for(auto p:mp) cout<<p.first<<" "<<p.second<<endl;
return 0;
}