算法上机复习

本文最后更新于:3 年前

最近算法实验要上机考试,所以还是准备一下吧(还不是因为自己太菜了)

16级题目

问题 A: 星空梦想——鲁班

题目描述

鲁班七号是王者峡谷里的射手,站撸英雄。战场上的鲁班七号,机制强大的鲨嘴炮,立刻将挡在前路的任何物体轰飞。正如他所说的,“借你们的肉体试验下新发明的威力”。是的,这就是鲁班大师和他的天才机关造物鲁班七号。然而,鲁班最为致命的缺点是腿短,跑得慢,一个稍不留神,便会被刺客所击杀。

既然腿短,那么就来多多运动吧,跳跳台阶可还行?假设鲁班七号一次可以跳上1级台阶,但极限一次只能跳上2级台阶(腿短没办法,嘤嘤嘤)。鲁班七号现在从0级阶梯开始,最终跳上第n级的台阶,求总共有多少种跳法?

输入

多组测试用例。

第一行输入包含一个整数T(1<=T<=50),代表测试用例个数。

接下来T行,每行输入包含一个整数n(1<=n<=50),代表鲁班最终跳上了第n级台阶。

输出

每组测试用例对应一行输出,每行输出一个整数ans,代表鲁班最终跳上第n级台阶的跳法种数。

样例输入

3
3
4
50

样例输出

3
5
20365011074

提示

注意结果超过int范围,请用long long类型存储ans

#include<bits/stdc++.h>
using namespace std;
const int N=50;
long long f[N];
int main()
{
	f[0]=1,f[1]=1;
	for(int i=2;i<=50;i++)
	{
		f[i]=f[i-1]+f[i-2];
	}
	int n;
	cin>>n;
	while(n--)
	{
		int m;
		cin>>m;
		cout<<f[m]<<endl;
	}
	return 0;
 } 

问题 B: 午夜歌剧——元歌

题目描述

元歌是王者峡谷里的刺客。何谓至高机关之美呢?唯有以至高权力的手令太古奇迹重现人世,方能称得上啊。

是的,元歌擅长操控,所做傀儡能起到以假乱真的作用,今天元歌的傀儡变成你的初中数学老师,给你出个数学题:给你一个数字x,让你求出k7、k6、k5、k4、k3、k2、k1、k0(0<=ki<=9),使得以下等式1成立,最后根据等式2求出最终ans值。

等式1:

img

等式2:

img

输入

多组测试用例。

第一行输入包含一个整数T(1<=T<=1000),代表测试用例个数。

接下来T行,每一行包含一个整数x(1<=x<=1500000)。

输出

每组测试用例对应一行输出,每行输出一个整数ans,代表最终运算结果。

样例输入

3
7
143
3223193224

样例输出

10
151
163311433223

提示

测试数据均大于等于1,不用特判0

感觉图片等式有点问题,一开始没理解什么意思,后来看了学长的提示。本质就是进制转换。

#include<bits/stdc++.h>
using namespace std;
int t,m;
void convert(int n)
{
	int c,r;
	r=n%7;
	c=n/7;
	if(c>0)
	{
		convert(c);
		cout<<r;
	}
	else
	cout<<n;
} 
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>m;
		convert(m);
		cout<<endl;
	}
	return 0;
 }

问题 C: 圣诞恋歌——貂蝉

题目描述

貂蝉是王者峡谷里的法师/刺客,貂蝉打法一定要注意配合技能与被动。半肉出装加上蛇皮走位,往往可以1打5,轻松拿下5杀。语花印被动描述为:技能命中会为敌人叠加花之印记,叠加满4层后印记触发被动,会给自身回复生命,同时会对周围敌人造成真实伤害并减速。
我们现在对貂蝉的技能及被动进行简化如下:每使用1次技能会攻击1次目标,每攻击3次目标,会自动额外攻击1次目标。
现在,貂蝉在游戏中使用了n次技能,请问总共会给目标带来多少次攻击。

输入

多组测试数据,第一行输入包含一个整数T,代表测试样例个数。
接下来T行,每行输入包含一个整数n(1<=n<=100),代表貂蝉使用了n次技能。

输出

每组测试用例对应一行输出,每行输出一个整数ans,代表貂蝉对目标进行了ans次攻击。

样例输入

6
1
2
3
45
81

样例输出

1
2
4
57
121

提示

这题就是汽水瓶的改编。。。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n; 
	while(n--)
	{
		int m,sum;
		cin>>m;
		sum=0;
		while(m>3)
		{
			m=m-2;
			sum=sum+3;
		}	
		if(m==3)
		sum+=4;
		else
		sum=m;
		cout<<sum<<endl; 
	}
	return 0;
}

问题 D: 海之征途——孙策

题目描述

孙策是王者峡谷里的坦克/战士。大船靠岸,江郡欢呼着迎来了他们的新领袖,人称江东小霸王的年轻人。游戏中,孙策的技能长帆破浪,可以驾船冲锋,可将船撞向敌方单位或者阻挡物,并造成一定的伤害。

现在,有一群好奇的江郡小朋友想跟着孙策一起出海航行,但孙策的船承载不了所有小朋友,所以孙策决定,尽可能带更多的小朋友出海,现在请你帮孙策谋一个策略,使得更多的小朋友有机会出海航行。已知的条件是孙策船的最大载重m,以及n个小朋友的体重。

输入

多组测试用例。
第一行输入包含一个整数T(1<=T<=1000),代表测试用例个数。

每组测试用例第一行有两个整数m和n。(0<=m<=1000, 0<=n<=1000),分别代表船的载重重量和小朋友的个数,接下来一行为n个小朋友的体重。

输出

每组测试用例对应一行输出,每行输出一个整数ans,代表最多能有ans个小朋友跟着一起出海。

样例输入

2
10 4
3 5 2 4
20 9
3 5 2 4 6 1 8 5 9

样例输出

3
6

提示

就是简单的装在问题

#include<bits/stdc++.h>
using namespace std;
int T,m,n;
int w[1005];
int main()
{
	cin>>T;
	while(T--)
	{
		int ans=0;
		cin>>m>>n;
		for(int i=0;i<n;i++)
		{
			cin>>w[i];
		}
		sort(w,w+n);
		for(int i=0;i<n;i++)
		{
			if(m>=w[i])
			{
				ans++;
				m-=w[i];
			}
			else
			break; 
		} 
		cout<<ans<<endl;
	}
	return 0;
}

问题 E: 极冰防御——盾山

题目描述

盾山是王者峡谷里的辅助,一夫当关、万夫莫开,一个好的辅助往往可以给团队带来极大帮助。

盾山的游戏中的一个技能为不动如山:手握一块由石头组成的巨盾,张开巨盾砸向地面,将敌人推开,并持续一段时间。

假设盾山最多只能承受C重量的盾牌,而现在有N个小石头,每个石头i的重量为Wi,防御值为Pi。那么,呆萌的盾山想知道,他从N个小石头中挑选M个(M<=N)组成他可承受盾牌,最大的防御值是多少?

输入

多组测试用例。
第一行输入包含一个整数T(1<=T<=10),代表测试用例个数。

接下来有T组测试用例。每组测试用例第一行为盾山承受盾牌的最大重量C(C<10000)和小石头的个数N(N<1000)。接下来的N行分别为小石头的重量Wi(1<=Wi<=100)和防御值Pi(1<=Pi<=3000000)。

输出

每组测试用例对应一行输出,每行输出一个整数ans,代表可承受盾牌的最大防御值。

样例输入

1
10 5
2 6
2 3
6 5
5 4
4 6

样例输出

15

提示

01背包问题,不知道下面的解能不能过

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
long long ans[N];
int w[N],v[N];
int T;
int main()
{
	cin>>T;
	while(T--)
	{
		int C,N;
		memset(ans,0,sizeof(ans));
		cin>>C>>N;
		for(int i=0;i<N;i++)
		{
			cin>>w[i]>>v[i];
		}
		for(int i=0;i<N;i++)
		{
			for(int j=C;j>=w[i];j--)
			ans[j]=max(ans[j-1],ans[j-w[i]]+v[i]);
		}
//		for(int i=0;i<=C;i++)
//		cout<<ans[i]<<endl;
		cout<<ans[C]<<endl;
	} 
	return 0;
}

ps:以上代码没有提交测试环境,只是过了给出的测试样例。

dfs大合集

迷宫问题

题目描述

小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。
小明只能向上下左右四个方向移动。

输入

输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。
每组输入的第一行是两个整数N和M(1<=N,M<=100)。
接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。
字符的含义如下:
‘S’:起点
‘E’:终点
‘-’:空地,可以通过
‘#’:障碍,无法通过
输入数据保证有且仅有一个起点和终点。

输出

对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。

样例输入

1
5 5
s-###
-----
##---
E#---
---##

样例输出

9
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include <algorithm>
using namespace std;
int de[100][100];//计步数组  记录走到这个位置所需的步数 不能走到的位置标记为-1 
char map[100][100];  //用于存放迷宫地图 
typedef pair<int,int> P;  //坐标
int to[2][4]={1,-1,0,0,0,0,1,-1};  //在当前坐标下能走的四个方向
int sx,ex,sy,ey;  //(sx,sy)为起点坐标  (ex,ey)为终点坐标
int x,y,nx,ny; //(x,y)为函数中当前位置坐标   (nx,ny)为接下来能到达的坐标 
int r,l;  //r为行数 l为列数 
int bfs()
{
	memset(de,-1,sizeof(de));
	queue<P> qu;
	qu.push(P(sx,sy));   //将起点坐标放入队头 
	de[sx][sy]=0;
	while(!qu.empty()) 
	{
		P p=qu.front();   //取出队头坐标 
		qu.pop() ;//删除对头及走过的坐标 
		x=p.first,y=p.second; 
		if(x==ex&&y==ey) break; //到达终点 跳出循环		
	 	for(int i=0;i<4;i++)
		{
			nx=x+to[0][i];//开始向四个方向移动 
			ny=y+to[1][i];			
				if(nx>=0&&nx<r&&ny>=0&&ny<l&&map[nx][ny]!='#'&&de[nx][ny]==-1)
	 			//判断是否越界 以及是否能走  排除走过的路 
	 			{
			     	qu.push(P(nx,ny));      //将能走的坐标放入队列 之后依次删除 
			    	de[nx][ny]=de[x][y]+1;  //步数加一 
				} 				  
			}
	}
	if(de[ex][ey]==-1)  return -1;  //终点的记步数组为-1 及不能到达终点 
	else return de[ex][ey]; 
} 
int main()
{
	int n,i,j;
	while(cin>>n){
		while(n--){
			cin>>r>>l;
			for(i=0;i<r;i++){
				for(j=0;j<l;j++){ 
				cin>>map[i][j];
				if(map[i][j]=='S') //记录起点坐标 
				 {
					sx=i,sy=j;
				 } 
				 else if(map[i][j]=='T')  //记录终点坐标 
				 {
				 	ex=i,ey=j;
				 }
				}
			}
			cout<<bfs()<<endl;
		}
	}
	return 0;
}

acwing迷宫问题

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int mp[N][N];
int dis[N][N];
typedef pair<int,int> P;
int n,m;
int to[2][4]={1,-1,0,0,0,0,1,-1};
int x,y,nx,ny;
void dfs()
{
	memset(dis,-1,sizeof(dis));
	queue<P> qu;
	qu.push(P(0,0));
	dis[0][0]=0;
	while(!qu.empty())
	{
		P p=qu.front();
		qu.pop();
		x=p.first,y=p.second;
		if(x==n-1&&y==m-1) break;
		for(int i=0;i<4;i++)
		{
			nx=x+to[0][i],ny=y+to[1][i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&dis[nx][ny]==-1&&mp[nx][ny]==0)
			{
				qu.push(P(nx,ny));
				dis[nx][ny]=dis[x][y]+1;
			}
		 } 
		
	}
	if(dis[n-1][m-1]!=-1)
	cout<<dis[n-1][m-1];
	return; 
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
	cin>>mp[i][j];
	dfs();
	return 0;
}

n皇后问题

#include<bits/stdc++.h>
using namespace std;
int n,ans=0;
const int N=20;
char m[N][N];
bool col[N],dg[N],udg[N];
void dfs(int u)
{
	if(u==n)
	{
//		for(int i=0;i<n;i++)
//		cout<<m[i]<<endl;
		ans++;
		return;
	}
	for(int i=0;i<n;i++)
	{
		if(!col[i]&&!dg[i+u]&&!udg[n-u+i])
		{
			m[u][i]='Q';
			col[i]=dg[i+u]=udg[n-u+i]=1;
			dfs(u+1);
			col[i]=dg[i+u]=udg[n-u+i]=0;//回溯恢复现场 
			m[u][i]='.';
		}
	}
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		m[i][j]='.';
	dfs(0);
	cout<<ans;
	return 0;
}

m图着色问题

题目描述

给定无向连通图G和m种不同的颜色,用这些颜色给图的各个顶点着一种颜色,若某种方案使得图中每条边的2个顶点的颜色都不相同,则是一个满足的方案,找出所有的方案。

输入

第一行有3个正整数n,k和m,分别表示n个顶点,k条边,m种颜色
接下来k行,每行2个正整数,表示一条边的两个顶点

输出

所有不同的着色方案数

样例输入

5 8 4 
1 2
1 3 
1 4
2 3
2 4
2 5
3 4
4 5

样例输出

48

提示

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int mp[N][N];
int color[N]={0};
int n,k,m,ans=0;
void dfs(int d)
{
	if(d==n+1)
	{
		ans++;
		return;
	}
	
	for(int i=1;i<=m;i++)
	{
		int flag=1;
		for(int j=1;j<=n;j++)
		{
			if(mp[d][j]&&color[j]==i)
			{
				flag=0;
				break;
			}
		 }
		 if(flag)
		 {
		 	 color[d]=i;
			 dfs(d+1);
			 color[d]=0; 	
		 } 
	 } 
}
int main()
{
	cin>>n>>k>>m;
	for(int i=0;i<k;i++)
	{
		int t1,t2;
		cin>>t1>>t2;
		mp[t1][t2]=1;
		mp[t2][t1]=1;
	}
	dfs(1);
	cout<<ans<<endl;
	return 0;
}

部分和

题目描述

给定n个整数,判断是否可以从中选择若干数字,使得他们的和恰好为k。

输入

多组测试用例。

对于每组测试用例,第一行一个正整数n,第二行n个整数,第三行一个整数k。

1N20,输入整数及k均小于1e8

输出

若可以使得和为k,输出”Yes”,否则”No”。

样例输入

4
1 2 4 7
13

样例输出

Yes
#include<bits/stdc++.h>
using namespace std;
int s[25];
int n,m;
bool check(int l,int a)
{
	 if(a==m) return true;
	 if(l==n) return false;
	 if(check(l+1,a+s[l]))
	 return true;
	 if(check(l+1,a)) return true;
}

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>s[i];
	}
	cin>>m;
	if(check(0,0))
	cout<<"YES";
	else
	cout<<"NO"; 
	
	return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

 目录

Copyright © 2020 my blog
载入天数... 载入时分秒...