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;
}