算法训练24


1.知识点总结

这次是简单的练手( ̄▽ ̄)*100/100嗷!

题目 难度 知识点
1027 Colors in Mars 🎈 基础数学
1028 List Sorting 🎈 STL中sort
1029 Median 🎈 水题
1030 Travel Plan 🎈 Dij+DFS

2. 分题题解

2.1 1027 Colors in Mars

注意“00”的情况和前面缺单个0的情况

#include<bits/stdc++.h>
using namespace std;
int r,g,b;
char table[]="0123456789ABC";
void to10(int &num){
	
}
void convert(int num){
	string ans="";
	while(num){
		ans+=table[num%13];
		num/=13;
	}
	if(ans.length()==1){
		ans+="0";
	}else if(ans.length()==0){
		ans="00";
	}
	reverse(ans.begin(),ans.end());
	printf("%s",ans.c_str());
}
int main(){
	scanf("%d%d%d",&r,&g,&b);
	printf("#");
	convert(r);
	convert(g);
	convert(b);	
	return 0;
} 

2.2 1028 List Sorting

sort的送分题,注意审题即可~

#include<bits/stdc++.h>
using namespace std;
struct Student{
	int id;
	string name;
	int grade;
};
int N,C;
bool cmp1(Student a,Student b){
	return a.id<b.id;
}
bool cmp2(Student a,Student b){
	if(a.name!=b.name)
		return a.name<b.name;
	else 
		return a.id<b.id;
}
bool cmp3(Student a,Student b){
	if(a.grade!=b.grade)
		return a.grade<b.grade;
	else 
		return a.id<b.id;
}
vector<Student>stu;
int main(){
	scanf("%d%d",&N,&C);
	stu.resize(N);
	for(int i=0;i<N;i++){
		cin>>stu[i].id>>stu[i].name>>stu[i].grade;
	}
	switch(C){
		case 1:
			sort(stu.begin(),stu.end(),cmp1);
			break;
		case 2:
			sort(stu.begin(),stu.end(),cmp2);
			break;
		case 3:
			sort(stu.begin(),stu.end(),cmp3);
			break;
	}
	for(int i=0;i<N;i++){
		printf("%06d ",stu[i].id);
		cout<<stu[i].name<<" "<<stu[i].grade<<"\n";
	}
	return 0;
}

2.3 1029 Median

水题,不值得25分的感觉🤣,这几年不会考着种简单题目der~

但是注意数据类型开了Long Long

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll>v;
int num;
ll temp;
int sum=0;
int main(){
	scanf("%d",&num);
	sum+=num;
	for(int i=0;i<num;i++){
		scanf("%lld",&temp);
		v.push_back(temp);
	}
	scanf("%d",&num);
	sum+=num;
	for(int i=0;i<num;i++){
		scanf("%lld",&temp);
		v.push_back(temp);
	}
	sort(v.begin(),v.end());
	printf("%lld",v[(sum-1)/2]);
	return 0;
}

2.4 1030 Travel Plan

是比较常考的题型,Dij加上深搜回溯。

首先利用Dijkstra算法找到最短路径,并记录在pre二维数组中,接着dfs搜索pre中cost最小的结果保存作为最后的path

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int inf=INT_MAX;
int N,M,S,D; 
vector<vector<int>>graph_d;
vector<vector<int>>graph_c;
vector<vector<int>>pre;
//输出答案
int ans_d; 
int ans_c=inf;
vector<int>path;
//获取路径
void getPath(int id,vector<int>temp,int cost){

	if(id==S){
		if(cost<ans_c){
			ans_c=cost;
			path=temp;
		}
	}else{
		for(int i=0;i<pre[id].size();i++){
			temp.push_back(pre[id][i]);
			getPath(pre[id][i],temp,cost+graph_c[id][pre[id][i]]);
			temp.pop_back();
		}
	} 
} 
//dij算法
void Dij(int bg,int ed){
	vector<bool>vis(N,false);
	vector<int>dis(N,inf);
	dis[bg]=0;
	while(1){
		int u=-1;
		int min_dis=inf;
		for(int i=0;i<N;i++){
			if(!vis[i]&&dis[i]<min_dis){
				min_dis=dis[i];
				u=i;
			}
		}
		if(u==-1){
			break;
		}
		vis[u]=true;
		for(int v=0;v<N;v++){
			if(graph_d[u][v]!=inf){
				if(dis[v]>dis[u]+graph_d[u][v]){
					pre[v].clear();
					pre[v].push_back(u);
					dis[v]=dis[u]+graph_d[u][v];
				}else if(dis[v]==dis[u]+graph_d[u][v]){
					pre[v].push_back(u);
				}
			}
		}
	}
	vector<int>temp;
	temp.push_back(D);
	getPath(D,temp,0);
	ans_d=dis[ed];
} 
int a,b,c,d;

int main(){
	scanf("%d%d%d%d",&N,&M,&S,&D);
	//初始化
	graph_d.resize(N);
	for(int i=0;i<N;i++){
		graph_d[i].resize(N);
		fill(graph_d[i].begin(),graph_d[i].end(),inf);
	} 
	graph_c.resize(N);
	for(int i=0;i<N;i++){
		graph_c[i].resize(N);
		fill(graph_c[i].begin(),graph_c[i].end(),inf);
	} 
	pre.resize(N);
	//输入
	for(int i=0;i<M;i++){
		scanf("%d%d%d%d",&a,&b,&d,&c);
		graph_d[a][b]=d;
		graph_d[b][a]=d;
		graph_c[a][b]=c;
		graph_c[b][a]=c;
		
	} 
	//Dij算法
	Dij(S,D);
	for(int i=path.size()-1;i>=0;i--){
		printf("%d ",path[i]);
	}
	printf("%d %d",ans_d,ans_c);
	return 0;
}

3. 参考资料


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