算法导论集(2)

A. 考试成绩分析

Description

期中考试结束后,吴明老师想知道自己班上某一门课程成绩的分布情况,请你编一个程序帮一下吴明老师。现在已知班上有n名同学以及每个同学的成绩,吴老师最想知道的是两个同学成绩的最大差距。

Input

本问题有多组测试数据,每组测试数据有两行,第一行是同学的人数n(2<=n<=100),第二行是用空格隔开的n个同学的成绩ai(0<=ai<=100)。

Output

对于每组测试数据,输出只有一行,即两个同学成绩的最大差距。

Sample Input

7
80 100 65 90 71 99 48

Sample Output

52
#include <stdio.h>

int main() {
    int n;
    while (scanf("%d", &n) == 1 && n >= 2 && n <= 100)
    {
        int scores[n], min_score = 101, max_score = 0;

        // 输入并获取每个同学的成绩
        for (int i = 0; i < n; ++i) {
            scanf("%d", &scores[i]);
            if (scores[i] < min_score) {
                min_score = scores[i];
            }
            if (scores[i] > max_score) {
                max_score = scores[i];
            }
        }

        // 计算并输出最大差距
        printf("%d\n", max_score - min_score);

        // 清除剩余的换行符,以便读取下一组数据
        getchar();
    }

    return 0;
}

B. 抄近路

Description

有一个学校的宿舍楼的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3...,当排满一行时,从下一行相邻的楼往反方向排号。例如:小区为 3 行 6 列,矩阵排列方式:

要求:已知宿舍楼的楼房有 w 列及两个楼房楼号 m 和 n,求从 m 号楼到 n 号楼之间的最短路线经过几个楼(不能斜线方向移动)。例如上图:当 w=6,m=8,n=2,从 8 号楼到 2 号楼最短的路线经过 5,4,3,2 四个楼(9,10,11,2 也经过四个楼),故最短路线为 4(注:不考虑路线只考虑最短路线经过几个楼)。最短距离。输入三个正整数 w(1<w<21),m(1<m<10001),n(1<n<10001),且 m 不等于 n。三个正整数之间以一个空格隔开,输出 m 到 n 的最短路线经过几个楼。

Input

在一行输入三个正整数 w,m,n,三个正整数之间以一个空格隔开。

Output

输出 m 到 n 的最短路线经过几个楼。

Sample Input

6 8 2

Sample Output

4

#include<bits/stdc++.h>

using namespace std;

struct TRooms

{

	int nRow;

	int nCol;

};

TRooms tFind(int nWidth,int nRoom);

int main()

{
	int w,m,n;
	TRooms ta,tb;
	cin>>w>>m>>n;
	ta=tFind(w,m);
	tb=tFind(w,n);
	cout<<abs(ta.nCol-tb.nCol)+abs(ta.nRow-tb.nRow)<<endl;
return 0;
}
TRooms tFind(int nWidth,int nRoom)
{
	int x,y;
	TRooms tRet;
	x=nRoom/nWidth;
	y=nRoom%nWidth;
	if(y==0)
	{
		y=nWidth;
	}
	else
	{
		x++;
	}
	if(x%2==0)
	{
		y=nWidth+1-y;
	}
	tRet.nRow=x;
	tRet.nCol=y;
	return tRet;

}

C. 验证尼科彻斯定理

Description

尼科彻斯定理告诉我们,任何一个正整数n的立方都可以表示成若干个相邻的奇数之和,现在请你编程序验证一下。

Input

本问题有多组测试数据,对于每组测试数,输入只有一行,即正整数n(1<=n<=1000)。

Output

对于每组测试数据,输出有2部分,第一部分只有一行即”n=”n;第二部分有若干行,每行一个表达式,相邻奇数项数少的在前,每个表达式奇数小的在前,格式参见sample。

Sample Input

4
3

Sample Output

n=4
64=31+33
64=13+15+17+19
64=1+3+5+7+9+11+13+15
n=3
27=27
27=7+9+11

#include<bits/stdc++.h>
using namespace std;
void vEven(int x);
void vOdd(int x);
void vOut(int nX,int nV);
int main()
{

	int n;
	while(cin>>n)

   {
		cout<<"n="<<n<<endl;
		if(n%2==0)
		{
			vEven(n);
		}

		else
		{
			vOdd(n);
		}

	}
		return 0;

}
		void vEven(int x)
		{
			int i,temp;
			i=2;
			temp=x*x*x;
			while(i<=sqrt(temp+0.1))
				{
					if(temp%(2*i)==0)
					{
						vOut(i,temp/i);
					}
						i+=2;
				}

		}
void vOut(int nX,int nV)
{
	int i,temp;
	temp=nV-(nX-1);;
	cout<<nX*nV<<"="<<temp;
	for(i=2;i<=nX;i++)
		{
		temp+=2;
		cout<<'+'<<temp;
		}
		cout<<endl;
}
void vOdd(int x)
{
	int i,temp;
	i=1;
	temp=x*x*x;
	while(i<=sqrt(temp+0.1))
	{
	if(temp%i==0)
	{
		vOut(i,temp/i);
	}
		i+=2;

	}

}

D. 食堂排队买菜问题系列之三

Description

学院有好几个食堂,每当中午下课吃饭时,人会很多,菜品也有很多,而且每个同学的口味也可能不同,同一寝室或同一班级的同学相互之间关系也不错,所以每个同学买的菜不一定仅仅给自己吃,有的还需要帮其他同学打包。现在知道菜品的种数以及每种菜品打菜所需时间,如果还告诉你每个同学打菜的菜品,共有n同学排队要买自己喜欢吃的饭菜(包括帮其他同学打包的菜),请你求出一种排队次序,使所有同学买好饭菜的时间总和为最小(单位为分钟,以下同,需要指出的是除了第一个学生不用等待,直接买菜外,后面的同学所需买好菜的时间包括等待和打菜的时间,一个同学打完菜后后面的同学才能打菜)。

Input

输入有多组测试数据,对于每组数据,输入有三部分,第一部分只有一行是用空格隔开的两个正整数m和n,其中m(1<=m<=10000)表示学生的总人数,n(1<=n<=26)表示菜的品种数;第二部分也只有一行是n个用空格隔开的正整数,分别表示n种菜品各自需要的打菜时间(1<=打菜时间<=100),第三部分有m行,每行是一个由大写字母组成的字符串(大写字母可以相同或重复出现,但字符串长度不超过100,即打菜的菜品可以重复,但总份数不超过100),每个大写字母表示学生需要打的菜品,A表示第一种菜品,B表示第二种菜品,以此类推,一个同学不同的菜品打菜的先后顺序不影响后面同学的等待时间。

Output

对于每组输入,输出只有一行,表示m个同学买好饭菜所需时间的总和的最小值。

Sample Input

3 5
3 1 4 2 5
ACE
BBA
ABDB

Sample Output

41

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10001
int nCost[MAXN];
string s[MAXN];
	int main()
	{
		int m,n,nMenu[26],nSize,i,j;
		long long nAns,nT;
		while(cin>>m>>n)
	{
	memset(nMenu,0,sizeof(nMenu));
	for(i=0;i<n;i++)
	{
		cin>>nMenu[i];
	}
	for(i=1;i<=m;i++)
	{
		cin>>s[i];
		nSize=s[i].size();
		nT=0;
		for(j=0;j<nSize;j++)
			{
			nT+=nMenu[s[i][j]-'A'];
			}
			nCost[i]=nT;
			}
	sort(nCost+1,nCost+1+m);
	nAns=0;
	nT=0;
	for(i=1;i<=m;i++)
		{
		nT+=nCost[i];
		nAns+=nT;
		}
	cout<<nAns<<endl;
	}
	return 0;
	}

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法导论是计算机科学中非常重要的一门课程,它涵盖了计算机算法的设计、分析与应用。期末复习是为了加深对所学知识的理解和掌握,为考试做好充分准备。 使用Python语言进行算法导论的复习是一种很好的选择。Python是一种强大且易于上手的编程语言,具有简洁的语法和丰富的库支持。下面是几个复习的重点: 1. 熟悉Python的基本语法和数据结构:掌握Python的基本数据类型如列表、字典和集合,并了解它们的操作与性能。 2. 掌握常见排序算法:复习插入排序、归并排序、快速排序等常见的排序算法,并能够灵活应用它们解决实际问题。 3. 熟悉图算法:学习图的表示方法,以及广度优先搜索(BFS)和深度优先搜索(DFS)等基本的图算法。 4. 熟练应用动态规划算法:了解动态规划的基本思想,复习使用动态规划解决背包问题、最长公共子序列等典型问题。 5. 学习贪心算法:了解贪心算法的概念和特点,熟悉使用贪心算法解决活动选择、哈夫曼编码等问题。 6. 熟练掌握分治算法:复习分治算法的基本思想和应用,熟悉使用分治算法解决最大子数组和矩阵乘法等问题。 7. 复习基本的算法分析方法:熟悉时间复杂度和空间复杂度的概念,掌握算法的渐进分析方法。 在复习过程中,可以通过参考教材、课堂笔记和习题集等资料进行练习和巩固所学知识。此外,可以参考一些算法导论的相关网上资源和在线教育平台上的课程进行深入学习。最重要的是,要坚持刷题,多进行实际编码练习,巩固所学算法的理解和应用能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值