23.复习

1.设置输出数字宽度

#include <iostream>

using namespace std;

int main(){
    int a=123456789,b=0,c=-1;
    printf("%8d %8d %8d",a,b,c);
    return 0;
}

2.保留小数点位数

#include <iostream>

using namespace std;

int main(){
    double a;cin>>a;
    printf("%.3lf\n",a);
    return 0;
}

3.闰年判定

四年一润且百年不润,或者四百年一润
#include <iostream>

using namespace std;

int main(){
    /*
     * 四年一润且百年不润,或者四百年一润
     * */
    int y;cin>>y;
    if(y%4==0&&y%100!=0||y%400==0){
        cout<<"YES"<<endl;
    }
    else
        cout<<"NO"<<endl;
    return 0;
}

4.不借助数组的循环找最值

#include <iostream>
#include <climits>
using namespace std;

int main(){
    int n;cin>>n;
    int mx=INT_MIN,mi=INT_MAX;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        if(mx<x) mx=x;
        if(mi>x) mi=x;
    }
    cout<<mx-mi<<endl;
    return 0;
}
#include <iostream>
#include <climits>
using namespace std;

int main(){
    int n,x;cin>>n;cin>>x;
    int mx=x,mi=x;
    for(int i=2;i<=n;i++){
        cin>>x;
        if(mx<x) mx=x;
        if(mi>x) mi=x;
    }
    cout<<mx-mi<<endl;
    return 0;
}

5.模运算性质

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#include <iostream>
#include <climits>
using namespace std;
const int mod=1000;
int main(){
    int a,b,ans=1;cin>>a>>b;
    for(int i=1;i<=b;i++){
        ans=(ans%mod*a%mod)%mod;
    }
    cout<<ans<<endl;
    return 0;
}
#include <iostream>
#include <climits>
using namespace std;
const int mod=1e6;
int main(){
    int n,ans=1,sum=0;cin>>n;
    for(int i=1;i<=n;i++){
        ans=(ans%mod*i%mod)%mod;
        sum=(sum%mod+ans%mod)%mod;
    }
    cout<<sum<<endl;
    return 0;
}

6.最大公约数、最小公倍数

#include <iostream>
#include <climits>
using namespace std;
//12 24
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;
}

7.素数

小素数判定(小于1e9)—试除法
小优化–>i遍历到根号x之前即可
#include<iostream>
using namespace std;

bool check(int x) {
	if (x < 2) return false;
	//注意:此处只需要遍历到根号前即可
	for (int i = 2; i <= sqrt(x);i++) 
		if (x % i == 0) return false;
	return true;
}
int main() {
	//小素数判定- 试除法

	int a, b;  cin >> a >> b;
	for (int i = a; i <= b; i++) {
		if (check(i)) cout << i << endl;
	}

	return 0;
}

8.特判完全平方数

#include <iostream>
#include <climits>
#include <cmath>
using namespace std;

int main(){
    int x;cin>>x;
    if(sqrt(x)==int(sqrt(x))){
        cout<<"YES";
    }
    else{
        cout<<"NO"<<endl;
    }
    return 0;
}

9.分解质因子

#include <iostream>
#include <climits>
#include <cmath>
using namespace std;

int main(){
    int n;cin>>n;
    int i=2,flag=0;
    cout<<n<<"=";
    while(n!=1){
        if(n%i==0){
            if(!flag){
                cout<<i;
                flag=1;
            }
            else{
                cout<<"*"<<i;
            }
            n=n/i;
        }
        else{
            i++;
        }
    }
    return 0;
}

10.埃氏筛

#include <iostream>
#include <climits>
#include <cstring>

using namespace std;
const int N=1e3+10;
bool vis[N];//标记数组
int primes[N],id;//素数表
void E_sieve(int n){
    //默认0是素数
//    vis[0]=vis[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            primes[++id]=i;
            for(int j=i*i;j<=n;j=j+i){
                vis[j]=1;
            }
        }
    }
}
int main(){
    int n;cin>>n;
    E_sieve(n);
    for(int i=1;i<=id;i++){
        cout<<primes[i]<<" ";
    }
    return 0;
}

11.最长平台

<注意>:r一定要走到n+1的位置上,因为如果最长平台出现在末尾,r必须走到末尾的下一位,这样r-l的长度才正确
#include <iostream>

using namespace std;
const int N=1e5+10;
int a[N],n,maxlen=1;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    /*
     *   1  2  3  4  5  6  7  8  9  10
     * a 1  2  2  3  3  3  5  5  5  5
     *                     l          r
     * */
    int l=1,r=2;
    while(r<=n+1){
        if(a[l]!=a[r]){
            maxlen=max(maxlen,r-l);
            l=r;
        }
        r++;
    }
    cout<<maxlen<<endl;
    return 0;
}

12.线性模拟环

线性扩增2倍模拟环
#include <iostream>
#include <stack>

using namespace std;

int main(){
	string s,subs;cin>>s>>subs;
	if(s.size()<subs.size()) swap(s,subs);
	s=s+s;//线性扩增二倍模拟环
	if(s.find(subs)!=-1){
		cout<<"true"<<endl;
	} 
	else{
		cout<<"false"<<endl;
	}
	return 0;
}

13.表达式求值(stack)

前缀表达式

#include <iostream>
#include <stack>
#include <string>

using namespace  std;

const int N=1e4+10;
string s[N];
int id=0;

int main(){
	string str;
	while(cin>>str){
		s[++id]=str;
	} 
//	for(int i=1;i<=id;i++){
//		cout<<s[i]<<" ";
//	}
	//前缀表达式的求解
	stack<double> stk;
	for(int i=id;i>=1;i--){
		if(s[i][0]>='0'&&s[i][0]<='9'){//如果是数字就入栈 
			stk.push(stod(s[i]));
		}
		else if(s[i][0]=='+'){
			double a,b;
			a=stk.top();stk.pop();
			b=stk.top();stk.pop();
			stk.push(a+b);
		}
		else if(s[i][0]=='-'){
			double a,b;
			a=stk.top();stk.pop();
			b=stk.top();stk.pop();
			stk.push(a-b);
		}
		else if(s[i][0]=='*'){
			double a,b;
			a=stk.top();stk.pop();
			b=stk.top();stk.pop();
			stk.push(a*b);
		}
		else if(s[i][0]=='/'){
			double a,b;
			a=stk.top();stk.pop();
			b=stk.top();stk.pop();
			stk.push(a/b);
		}
	}	
	printf("%lf\n",stk.top());
    return 0;
}

中缀表达式

#include <iostream>
#include <stack>
#include <string>
#define int long long
using namespace  std;

string s;

signed main(){
	int num=0;
	char sign='+';
	stack<int> stk;
	cin>>s;
	for(int i=0;i<s.size();i++){
		if(s[i]>='0'&&s[i]<='9'){
			num=num*10+s[i]-'0';
		}
        //此处必须为if不能为else if因为最后一个数字不但要参入计算num,还要
		//对栈进行操作 
		if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||i==s.size()-1){
            if(sign=='+'){
                stk.push(num);
            }
            else if(sign=='-'){
                stk.push(-num);
            }
            else if(sign=='*'){
                stk.top()=stk.top()*num;
            }
            else if(sign=='/'){
                stk.top()=stk.top()/num;
            }
            num=0;
            sign=s[i];
        }
	}
	int ans=0;
	while(!stk.empty()){
		ans+=stk.top();stk.pop();
	}
	cout<<ans<<endl;
    return 0;
}

后缀表达式

#include <iostream>
#include <stack>
#define int long long
using namespace std;

signed main(){
	stack<int> stk;
	string s;
	while(cin>>s){
		if(s[0]>='0'&&s[0]<='9'){
			stk.push(stoll(s));
//			cout<<stk.top()<<endl;
		}
		else{
//			cout<<s<<endl;
			for(int i=0;i<s.size();i++){
				if(s[i]=='@') break;
				int b=stk.top();stk.pop();
				int a=stk.top();stk.pop();
				if(s[i]=='+'){
					stk.push(a+b);
				}
				else if(s[i]=='-'){
					stk.push(a-b);
				}
				else if(s[i]=='*'){
					stk.push(a*b);
				}
				else if(s[i]=='/'){
					stk.push(a/b);
				}
			}
		}
	}
	cout<<stk.top()<<endl;
	return 0;
}

14.搜索与回溯

二维迷宫类问题的搜索与回溯问题

马走日

#include <iostream>
#include <cstring>
using namespace std;
const int N=50;
int g[N][N],n,m,sx,sy,cnt;
bool vis[N][N];
int dx[]={-2,-2,-1,-1,1,1,2,2},dy[]={1,-1,2,-2,2,-2,1,-1};
struct node{
	int x,y,depth;
};
void dfs(node s){
	if(s.depth==n*m){
		cnt++;
		return;
	}
	for(int i=0;i<8;i++){
		int bx=s.x+dx[i],by=s.y+dy[i];
		if(bx<1||bx>n||by<1||by>m||vis[bx][by]) continue;
		vis[bx][by]=1;
		dfs({bx,by,s.depth+1});
		vis[bx][by]=0;
	}
}
void solve(){
	cin>>n>>m>>sx>>sy;sx++;sy++;
	memset(vis,0,sizeof vis);
	cnt=0;
	vis[sx][sy]=1;
	dfs({sx,sy,1});
	cout<<cnt<<endl;
}
int main(){
	int t;cin>>t;
	while(t--){
		solve();
	}	
	return 0;
}
#include <iostream>
#include <cstring>
using namespace std;
const int N=50;
int n,k,cnt[N];
bool vis[N];
void dfs(int depth,int start){
	//终止条件: 
	if(depth==k+1){
		for(int i=1;i<=depth-1;i++){
			printf("%3d",cnt[i]);
		}cout<<endl;
		return;
	}
	//枚举方案数: 
	for(int i=start;i<=n;i++){
		//判断是否需要标记: 
		if(!vis[i]){
			vis[i]=1;
			cnt[depth]=i;
			//搜索 : 
			dfs(depth+1,i);
			//回溯 : 
			vis[i]=0;
		}
	}
}
int main(){
	cin>>n>>k;
	dfs(1,1);
	return 0;
}

15.每日一题:外观数列

#include <iostream>
#include <vector>
using namespace std;
//33111
//    i
string solve(string& s){
	vector<int> vec;
	int cnt=1;
	for(int i=0;i<s.size();i++){
		if(i==s.size()-1){
			vec.push_back(cnt);
			vec.push_back(s[i]-'0');
		}
		else if(s[i]!=s[i+1]){
			vec.push_back(cnt);
			vec.push_back(s[i]-'0');
			cnt=1;
		}
		else if(s[i]==s[i+1]){
			cnt++;
		}
	}
	int num=0;
	for(auto it:vec){
		num=num*10+it;
	}
	return s=to_string(num);
}
int main(){
	string s;
	int n;cin>>s>>n;
	for(int i=1;i<=n-1;i++){
		s=solve(s);
	}
	cout<<s<<endl;
	return 0;
} 

16.删除问题

删完最小

#include <iostream>
#include <cstring>
#include <vector>
#include <string> 
using namespace std;
//69134 2
//934a
// j
//1234a 2
//34
//12345s-1
//99876a 2
//    j
//998a

int main(){
	string s;int k;cin>>s>>k;
	s=s+'a';
	for(int i=1;i<=k;i++){//每次循环删一个数,一共删k次 
		for(int j=0;j<=s.size()-2;j++){
			if(s[j]<s[j+1]){
				s.erase(s.begin()+j);
				break;
			}
		}
	}	
	s.pop_back();
	cout<<s<<endl;
	return 0;
}

删完最大

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
#define int long long
string s;


signed main(){
    cin>>s;
    s=s+'0';
    int n;cin>>n;
    while(n--){
        for(int i=0;i<s.size()-1;i++){
            if(s[i]>s[i+1]){
                s.erase(s.begin()+i);
                break;
            }
        }
    }
    s[s.size()-1]='\0';
    cout<<stoi(s)<<endl;
    return 0;
}

17.小松鼠聚会

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int N=1e6+10;
vector<int> g[N];
bool vis[N];
int a[N];
int n,m,k,ans;
struct node{
    int x,depth;
};
void bfs(node s){
    queue<node> q;
    q.push(s);vis[s.x]=1;
    while(!q.empty()){
		node cur=q.front();q.pop();
		if(cur.depth-1<=k){
			ans+=a[cur.x];
		}
		else{
			break;
		}
		for(int i=0;i<g[cur.x].size();i++){
			int id=g[cur.x][i];
			if(!vis[id]){
				q.push({id,cur.depth+1});vis[id]=1;
			}
		}
    }
}
int main(){
    cin>>n;m=n-1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        int u,v;cin>>u>>v;
        g[u].push_back(v);g[v].push_back(u);
    }
    cin>>k;
    for(int st=1;st<=n;st++){
        memset(vis,0,sizeof vis);
        ans=0;
        bfs({st,1});
        cout<<ans<<endl;
    }
    return 0;
}

18.dijkstra求单源最短路

邻接矩阵版本

#include<iostream>
#include<climits>
#include<algorithm>
using namespace std;
const int N = 1e4 + 10, INF = INT_MAX;
int g[N][N];//邻接矩阵
int mindis[N];//最短路数组,mindis[i]代表起点到i点的最短路
bool vis[N];
int n, m, s;
//邻接矩阵版dijkstra,同时可以处理重边和边权为0的情况
void dijkstra(int s) {
    //dijkstra第一步:集合中起点值置0
    mindis[s] = 0;
    for (int i = 1; i <= n; i++) {
        //dijkstra性质:每次循环从集合中找到未被标记过的最小值(和下标),该最小值就是起点到该点的最小值
        int mi = INT_MAX, minId = 0;
        for (int j = 1; j <= n; j++) {
            if (!vis[j] && mindis[j] < mi) {
                mi = mindis[j];
                minId = j;
            }
        }
        //找到起点到该点的最小值立马标记
        vis[minId] = 1;
        //dijkstra以minId作为中转点,向外进行扫描,更新起点到其他个点的最短距离即mindis数组
        for (int j = 1; j <= n; j++) {
            if (!vis[j] && g[minId][j]!=INT_MAX) {
                //mi是起点到minId的最短距离+minId到j距离 < 当前起点到j的最短距离
                if (mi + g[minId][j] < mindis[j]) {
                    mindis[j] = mi + g[minId][j];
                }
            }
        }
    }
}
int main() {
    cin >> n >> m >> s;
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) g[i][j] = INT_MAX;
    for (int i = 1; i <= m; i++) {
        int u, v, w; cin >> u >> v>> w;
        //有向图注意单向连边
        g[u][v] = min(g[u][v], w);//本题有重边,在所有的重边里面找到最小值
    }
    fill(mindis, mindis + N, INF);
    dijkstra(s);

    for (int i = 1; i <= n; i++) cout << mindis[i] << " ";
    return 0;
}

邻接表版本

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
#define int long long
const int N=1e4+10,MX=INT_MAX;
vector<pair<int,int>> g[N];
int n,m,st,mindis[N],vis[N];
void dijkstra(int s){
    mindis[s]=0;
    //每次循环标记mindis集合中的一个,标记了相当于找对了起点到该点的最短路,n个都标记了说明dij算法已经完成 
    for(int i=1;i<=n;i++){
        //dijkstra性质:每次循环找点未被标记过的最小值(和下标),该最小值就是起点到该点的最短路径
        int mi=INT_MAX,minId=0;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&mi>mindis[j]){
                mi=mindis[j];minId=j;
            }
        }
        //找到最小值意味着最短路找到了,要立马标记
        vis[minId]=1;
        //以mi最为中转站,访问它未被标记过的邻接点,更新mindis集合
        for(int j=0;j<g[minId].size();j++){
            int id=g[minId][j].first,w=g[minId][j].second;
            if(!vis[id]&&mi+w<mindis[id]) mindis[id]=mi+w;
        }
    }
}
signed main(){
    cin>>n>>m>>st;
    for(int i=1;i<=m;i++){
        int u,v,w;cin>>u>>v>>w;
        g[u].push_back({v,w});
    }
    fill(mindis,mindis+N,MX);
    dijkstra(st);
    for(int i=1;i<=n;i++) cout<<mindis[i]<<" ";
    return 0;
}

19.Floyd算法

多元最短路
O(n^3)
三层循环枚举中转站,起点,终点,更新mindis i j
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
const int N=1e3+10,INF=INT_MAX;
int mindis[N][N],n,m,st,t;

void Floyd(){
	//枚举中转站
	for(int k=1;k<=n;k++){
		//枚举起点
		for(int i=1;i<=n;i++){
			//枚举终点
			for(int j=1;j<=n;j++){
				//判断i k k j 之间是否有连边
				if(g[i][k]!=INF&&g[k][j]!=INF&&mindis[i][k]+mindis[k][j]<mindis[i][j]){
					mindis[i][j]=mindis[i][k]+mindis[k][j];
				} 
			} 
		} 
	} 
}
int main(){
	cin>>n>>m>>st>>t;
	fill(mindis[0],mindis[0]+N*N,INF);
	for(int i=1;i<=m;i++){
		int u,v,w;cin>>u>>v>>w;
		g[u][v]=g[v][u]=w;
	}
	Floyd();
	cout<<mindis[st][t]<<endl;
	return 0;
} 
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值