算法训练20


1. 题目总结

然后重新注册了一个账号重新开始刷,主要是如果不是模拟为背景的话,俺的效率真的一言难尽😶;可能刷过一次叭,还挺顺利的今天,一扫期末阴影啊哈哈哈

题目传送门 难度 知识点
1001 🎈 字符串
1002 🎈 字符串+STL
1003 🎈🎈 Dijkstra
1004 🎈🎈 二叉树

2. 分题题解

2.1 A+B Format

送分题,字符串处理

#include<bits/stdc++.h>
using namespace std;
int a ,b,sum;
string nans="";
bool flag=false;
int main(){
    scanf("%d%d",&a,&b);
    sum=a+b;
    if(sum<0){
        flag=true;
        sum=-sum;
    }
    string ans=to_string(sum);
    //输出答案
    int len=ans.length();
    int cnt=0;
    for(int i=len-1;i>=0;i--){
        cnt++;
        nans+=ans[i];
        if(cnt%3==0&&i){
            nans+=",";
        }
    }
    reverse(nans.begin(),nans.end());
    if(flag){
    	printf("-");
    	cout<<nans;
	}else{
		cout<<nans;
	}
    return 0;
}

2.2 A+B for Polynomials

多项式英文:Polynomials

也不卡时间空间,起始可以无脑开数组

#include<stdio.h>
#include<vector>
#include<set>
#include<map>
using namespace std;
map<int,double>pa,pb,pc;
set<int>Exps;
vector<int>ans_exps_sort;
int k,exp;
double num; 
int main(){
	scanf("%d",&k);
	for(int i=0;i<k;i++){
		scanf("%d%lf",&exp,&num);
		pa[exp]=num;
		Exps.insert(exp);
	}
	scanf("%d",&k);
	for(int i=0;i<k;i++){
		scanf("%d%lf",&exp,&num);
		pb[exp]=num;
		Exps.insert(exp);
	}
	//接下来是 
	for(set<int>::iterator it=Exps.begin();it!=Exps.end();it++){
		if(pa.find(*it)==pa.end()){
			pc[*it]=pb[*it]; 
			ans_exps_sort.push_back(*it);
		}else if(pb.find(*it)==pb.end()){
			pc[*it]=pa[*it];
			ans_exps_sort.push_back(*it);
		}else{
			//下面就是加
			if(pa[*it]+pb[*it]==0){
				continue;
			} else{
				pc[*it]=pa[*it]+pb[*it];
				ans_exps_sort.push_back(*it);
			}
		}
	}
	int len=ans_exps_sort.size();
	printf("%d",len);
	for(int i=len-1;i>=0;i--){
		printf(" %d %.1f",ans_exps_sort[i],pc[ans_exps_sort[i]]);
	}
	return 0;
}

2.3 Emergency

Dijkstra比较经典的题目,变式体现在每更新需要添加上一个结点pre的信息,按照题目要求回溯pre即可得到答案

#include<bits/stdc++.h>
using namespace std;
const int maxn=501;
const int inf=INT_MAX;
int N,M,st,ed;//城市个数、道路个数、起始、终止 
vector<int>city;//存每个城市的人数
//输出最短路径的个数,输出最多可以找多少人
int dis[maxn]; 
int graph[maxn][maxn];
bool vis[maxn]={false};
vector<vector<int> >pre;
int a,b,d;
void Dijkstra(int st,int ed){
	fill(dis,dis+N,inf);
	dis[st]=0;//起点到起点的距离最短
	int u,min_dis;
	for(int i=0;i<N;i++){
		u=-1;
		min_dis=inf;
		for(int j=0;j<N;j++){
			if(!vis[j]&&dis[j]<min_dis){
				u=j;
				min_dis=dis[j];
			} 
		}
		if(u==-1){
			return;
		}
		vis[u]=true;
		//更换中继节点
		for(int v=0;v<N;v++){
			if(!vis[v]&&graph[u][v]!=inf){
				if(dis[u]+graph[u][v]<dis[v]){
					pre[v].clear();
					pre[v].push_back(u);
					dis[v]=dis[u]+graph[u][v];//优化 
				}else if(dis[v]==dis[u]+graph[u][v]){
					pre[v].push_back(u);
				}	
			}
		}
	}
} 
int num=0,maxp=0;//最短路径个数、最大人头
//回溯前面的道路 
void dfs(int id,int people){
	if(id==st){
		num++;
		if(people>maxp){
			maxp=people;
		}
	}else{
		for(int i=0;i<pre[id].size();i++){
			dfs(pre[id][i],people+city[pre[id][i]]);
		}
	}
	return;
}
int main(){
	scanf("%d%d%d%d",&N,&M,&st,&ed);
	city.resize(N);
	pre.resize(N);
	for(int i=0;i<N;i++){
		scanf("%d",&city[i]);
	}
	fill(graph[0],graph[0]+maxn*maxn,inf);
	for(int i=0;i<M;i++){
		scanf("%d%d%d",&a,&b,&d);
		graph[a][b]=d;
		graph[b][a]=d;
	}
	Dijkstra(st,ed);
	dfs(ed,city[ed]);
	printf("%d %d",num,maxp);
	
	return 0;
}

2.4 Counting Leaves

数组版本的二叉树层次遍历,实际上比上一题简单

#include<bits/stdc++.h>
using namespace std;
int N,M;//N个结点,M个有子孙的结点 
bool isC[100]={false};
vector<vector<int> >nodes(100); 
int level[100]={0};
int cnts[100]={0};
int k,id;
int sum=1;//记录总层数 
void levelTravel(int root){
	queue<int>q;
	q.push(root);
	level[root]=1;
	while(!q.empty()){
		int top=q.front();
		sum=max(level[top],sum);
		q.pop();
		if(nodes[top].size()==0){
			cnts[level[top]]++;
		}
		for(int i=0;i<nodes[top].size();i++){
			q.push(nodes[top][i]);
			level[nodes[top][i]]=level[top]+1;
		}
	}
}
int temp;
int main(){
	scanf("%d%d",&N,&M);
	if(N==0){
		return 0;
	}
	for(int i=0;i<M;i++){
		scanf("%d%d",&id,&k);
		for(int j=0;j<k;j++){
			scanf("%d",&temp);
			nodes[id].push_back(temp);
			isC[temp]=true;
		}
	}
	levelTravel(1);
	for(int i=1;i<=sum;i++){
		if(i!=1)printf(" ");
		printf("%d",cnts[i]);
	}

	return 0;
} 

3. 参考资料

  • 《算法笔记》Dij

文章作者: Gao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Gao !
评论
  目录