【校编程训练解题报告1】(完整版)


版权声明:本文为 @iCurious
的原创文章,可以转载,但请务必注明作者和出处!!!
原文链接:|blog.csdn.net/icurious|www.blankspace.cn|www.cnblogs.com/icurious/|

Problem A: Let the Balloon Rise

Description

Contest time again! How excited it is to see balloons floating around. But to tell you a secret, the judges' favorite time is guessing the most popular problem. When the contest is over, they will count the balloons of each color and find the result.

This year, they decide to leave this lovely job to you.

Input

contains multiple test cases. Each test case starts with a number N (0 < N <= 1000) -- the total number of balloons distributed. The next N lines contain one color each. The color of a balloon is a string of up to 15 lower-case letters.

A test case with N = 0 terminates the input and this test case is not to be processed.

Output

For each case, print the color of balloon for the most popular problem on a single line.

Sample Input

5
green
red
blue
red
red
3
pink
orange
pink
0

Sample Output

red
pink

算法/思路

题目的意思实际输入一系列的字符串,代表ACM竞赛中升起气球的颜色,要做的就是输出出现次数最多的字符串。如果有多个则按照字母表顺序输出。
实质:统计字符串个数
我开始采用的是先统计个数再排序的思路:没出现一个单词,则对其个数进行+1,最后的按照字母表顺序输出出现次数最多的单词,但比较低效和耗费空间。所以换一种思路,先对输入的字符串数组进行排序再统计各个字符串出现的次数和去重处理

算法实现

先排序,再去重

#include <iostream>
#include <string>
using namespace std;

void StrSort(string s[],int lo,int hi)
{
	while(lo<--hi)
	{
		int mx=0;
		for(int i=lo+1;i<=hi;i++)
		{
			if(s[mx]<s[i])
				mx=i;//i就是每一趟最大值得下标
		}
		//cout<<s[mx]<<"<--swap_with-->"<<s[hi]<<endl;
		swap(s[mx],s[hi]);	
	}
}

int  main()
{
	int N;
	int i=0;
	//cin>>N;
	while(cin>>N&&N!=0)
	{
		string* s=new string[N];//用来存储各种颜色字符串的动态空间 
		for(i=0;i<N;i++){cin>>s[i];}//cout<<"s["<<i<<"]="<<s[i]<<endl;
		StrSort(s,0,N); 
		//for(i=0;i<N;i++){cout<<s[i]<<endl;}
		
		int* count=new int[N];//去重 
		for(i=0;i<N;i++){count[i]=0;}
		int l=0,r=0;
		while(++r<N)
		{
			if(s[l]==s[r])count[l]++;
			else {s[++l]=s[r];}
		}
		
		int size=l+1;//当前元素个数 
		int mx=0;
		//cout<<"size="<<size<<endl;
		for(i=0;i<size;i++)
		{
			//cout<<"count[]="<<count[i]<<" ";
			if(count[mx]<count[i])mx=i;	
			//cout<<"
mx="<<mx<<endl;
		}
		for(i=0;i<size;i++)
		{
			if(count[mx]==count[i])cout<<s[i]<<endl;	
		}			
		delete []count;		
		delete []s;		
	}
	return 0;
}

Problem B: 电梯调度

Description

The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.

For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.

Input

There are multiple test cases. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100. A test case with N = 0 denotes the end of input. This test case is not to be processed.

Output

Print the total time on a single line for each test case.

Sample Input

1 2
3 2 3 1
0

Sample Output

17
41

算法/思路

一个N层的大楼,有一部电梯,上楼6 min/层,下楼4 min/层,每层停五分钟,现在有X个人要坐电梯去各自的楼层,电梯一开始停在第0层就是地面上,让你求按照输入的顺序坐电梯需要花费的时间。
由于每个楼层都需要停5min,因此可以最后再加上去。假设第i个人要去第floor(i)个楼层,他之前的一个人要去floor(i-1)楼层,如果floor(i-1)<floor(i),那么电梯会在上楼阶段依次经过floor(i-1)和floor(i),上楼的时间就是6*(floor(i)-floor(i-1));如果floor(i-1)>floor(i),则需要在下楼的时候依次经过floor(i-1)和floor(i)。据此思路进行解答。

算法实现

#include <iostream>
using namespace std;

int main()
{
	int N;
	int el[101]={0};
	while(cin>>N&&N!=0)
	{
		for(int i=1;i<=N;i++)
		{
			cin>>el[i];			
		}
		int sum=0;
		for (int j=1;j<=N;j++)
		{
			(el[j]>el[j-1])?sum+=6*(el[j]-el[j-1]):sum+=4*(el[j-1]-el[j]);
			sum+=5;
		}
		cout<<sum<<endl;
	}
	return 0;
}

Problem C: Relaxed

Description

我们每隔一段时间就会观察一下我们周围一圈八支队伍的气球情况,如果他们的平均气球数少于或等于我们,我们就会很轻松,如果平均数多于我们,我们就会处于压力中。现在,已知我们队伍的气球数和其他八支队伍的气球数,你能算出我们是轻松还是处于压力中吗?

Input

第一行有一个整数T(1<=T<=100)表示数据的组数

接下来的T行,每行有9个整数(大于等于0,小于等于10),第一个整数代表我们队伍的气球数,接着的八个整数代表周围八支队伍的气球数

Output

每组数据输出一行
如果处于轻松状态,输出"Relaxed"
如果处于压力状态,输出"Stressed"

Sample Input

2
0 4 2 1 9 5 9 1 2
4 1 3 5 2 4 6 4 3

Sample Output

Stressed
Relaxed

算法/思路

计算平均值,坑点在数据类型,挺无聊的。向上取整比较大小的问题。

算法实现

#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main()
{	
	string s1="Stressed";
	string s2="Relaxed";
	int M=0;int n,w;
	cin>>M;
	while(M--)
		{
			int sum=0;
			cin>>w;
			for(int i=1;i<9;i++)
			{cin>>n;sum+=n;}
			//cout<<"ours="<<w<<",avg="<<sum<<"/8.0="<<ceil(sum/8.0)<<endl;
			string s=(w<ceil(sum/8.0))?s1:s2;
			cout<<s<<endl;
		}
	return 0;
}

Problem D: 漫长的旅程

Description

这次ACM/ICPC亚洲赛结束,我们从xx赛区要经过十分漫长的旅程才能返回xx,所以我们不得不找点有趣的事情做(比如说出这次比赛的题目…o(>﹏<)o)我们就想呀,这个火车就不能少停几站吗?当然,铁老大是不会同意滴。不过,铁老大也并非这么死板,火车沿途也不是所有站台都停靠,偶尔也是会跳过一些小站的。铁老大表示,可以跳过一些小站,但是绝对不能连续跳过两站及以上,否则又要成为众矢之的了。现在,某条线上一共有m个站台(火车初始停靠在第一站),铁老大想知道一共有多少种停站方案可供选择,你能帮助铁老大解决这个问题吗?

Input

输入数据首先包含一个整数N(N<=40),表示测试实例的个数,然后是N行数据,每行包含一个整数M(2<=M<=40),表示该线站台的数量。

Output

每组输出仅有一行,包含一个整数,表示可供选择的方案数。

Sample Input

2
2
3

Sample Output

1
2

算法/思路

本题的实质是经典的“走楼梯问题”,有一个M级的台阶,每次可以走1级或者2级,问走上台阶总共有多少种走法。
if M=1,f(M=1)=1
if M=2,f(M=2)=2,可能是从第0级,一下子走2级,或者0->1->2一次走一级。
if M=i,已经走到可第i级台阶了,那是怎么走上来的呢?可能是从第i-1级台阶走一步上来的,也可能是从第i-2级台阶走两部上来的,所以:
f(M=i)=f(M=i-1)+f(M=i-2),或者直接写成f(n)=f(n-1)+f(n-2),典型的斐波那契数列!!!

算法实现

#include<iostream>
using namespace std;
int fib(int n){return (n<=2)?1:fib(n-1)+fib(n-2);}
int main()
{int M=0,n=0;cin>>M;while(M--){cin>>n;cout<<fib(n)<<endl;}}

Problem E: Cards I

Description

There are 24 hours of train from xxx to xxx.
You know, the time is too long. It's really important to find some fun. So we buy a deck of cards. After each one gets its cards. It's better to sort these cards.
We don’t care about the color of the card and the jokers.
So there are only 13 kinds of card: 3 4 5 6 7 8 9 10 J Q K A 2.
This is also the order from the smaller to the bigger. You can see the rule is same with the Chinese poker in QQ.
Now I’ll give you the sequence of my cards, please output the card sequence in non-descending order.

Input

The first line is an integer T (1 <= T <= 10), indicates the number of test cases.
For each case, the first line is an integer N (1 <= N <= 100) indicates the number of cards
Then the following line is the N cards number (only A, J, Q, K and 2-10 is given).

Output

For each case output the card sequence in non-descending order in one line.

Sample Input

2
4
2 3 K 3
4
7 2 10 Q

Sample Output

3 3 K 2
7 10 Q 2

算法/思路

模拟扑克牌排序,斗地主应该都玩过,3最小,
这里没有考虑花色♦,♣,♠、对子、炸等,要不然真的可以斗上一桌了,哈哈。
对于输入的扑克牌,分别统计各出现多少张,然后按照规定的大小顺序输出。

算法实现

#include <iostream>
#include <string>
using namespace std;
int main()
{
		int N,n;cin>>N;int i,j,k;
		string pokers[]={"3","4","5","6","7","8","9","10","J","Q","K","A","2","King"};
		string card[200];
		while(N--)
		{
			cin>>n;
			for(i=0;i<n;i++)
			{
				cin>>card[i];
			}
			int co[13]={0};int flag=0;
			for(j=0;j<n;j++)
			{
				for(k=0;k<13;k++)
				if (card[j]==pokers[k])
				{
					if(k>flag)flag=k; //控制格式用
					co[k]++;
					//cout<<"co[k="<<k<<"]="<<co[k]<<endl;
				}
			}
			for (i=0;i<13;i++)
			{
				for (j=0;j<co[i];j++)
				{
					if(i==flag&&j==co[i]-1) cout<<pokers[i];
					else cout<<pokers[i]<<" ";
					//cout<<"pokers[i="<<i<<"]="<<pokers[i]<<" ";
				}

			}
			cout<<endl;
		}

	return 0;

}

Problem F: 矩阵乘法

Description

最近,斯坦福大学和加利福尼亚大学伯克利分校的几位算法大神发表了一篇论文,把矩阵乘法的复杂度降到了O(n2.3727),打破了沉睡20年的记录O(n2.376),以后的数值计算所有的相关书籍要被改写了!为了这个神一般的飞跃,我们做个题庆祝一下吧..._

若A为m×n矩阵,B为n×p矩阵,则他们的乘积AB会是一个m×p矩阵。其乘积矩阵的元素如下面式子得出:
matrix
矩阵乘法是可以结合的,即计算ABC,可以有(AB)C和A(BC)两种方法计算。但两种方法需要的乘法次数是不一样的。
举个例子:假设A为5010的矩阵,B 为1020的矩阵,C为205的矩阵。(AB)C,需要501020+50205=15000此乘法运算,而对于A(BC),则只需10205+5010*5=3500次乘法运算。
你现在的任务并不需要求最优的乘法次数,而是对于给出的矩阵乘法链,求它所需的乘法次数。

Input

测试包含多个用例,对于每个用例的第一行为2个整数n(1<=n<=26),m(1<=m<=100)分别代表矩阵的个数和待测试的矩阵乘法链个数。n=m=0代表输入结束。
接下来有n+m,第1-n行,每行由一个字母a(A-Z),两个整数b,c(1<=b,c<=100)组成。
第n+1到n+m行,每行为一个矩阵乘法链,由大写字母(A-Z)和‘(’,‘)’组成。可以用如下EBNF表达式表示(长度不超过100):
Exp = Matrix | "(" Exp Exp ")"
Matrix = "A" | "B" | "C" | ... | "X" | "Y" | "Z"

Output

对于每个矩阵乘法表达式,一行输出一个整数,代表该表达式所需的乘法次数。如果表达式有错误,则输出单词“error”。

Sample Input

3 7
A 50 10
B 10 20
C 20 5
A
B
(AA)
(AB)
(AC)
(A(BC))
((AB)C)
0 0

Sample Output

0
0
error
10000
error
3500
15000

算法/思路

由于给出加括号的方式,因此可以不必采取动态求矩阵连乘积,仿照括号匹配,运用栈结构:每遇到一个矩阵就push,遇到右括号就pop,并判断pop出的矩阵是否可以进行乘法运算:能,则统计运算的乘法次数,将结果保存为一个新的矩阵。否,则表达式错误,输出error。此外,对一些特殊的输入进行处理。

算法实现

#include <iostream>
#include <string>
#include <stack>
using namespace std;
struct mat{//m*n m=rows, n=cols
//	char name;
	int m;
	int n;
	//double data[MAXM][MAXN]; //预留一些功能,比如计算出最终的结果
};
void matMulCacl(string exp,mat a[])
{
			long rst=0;bool haveAns=true;			    
				stack<mat> s;
				while(!s.empty())s.pop();
				for(int i=0;exp[i];i++) 
				{
					//cout<<"exp["<<i<<"]="<<exp[i]<<endl;		
					if(exp[i]!='('&&exp[i]!=')')
					{	
						if(exp[i]>=65&&exp[i]<=90)//输入A-Z 
						{			
							int ii=exp[i]-65;
							if(ii>=0&&ii<=26)
							s.push(a[ii]);
							else {haveAns=false;break;}//找不到对应的矩阵 cout<<"error1"<<endl;			
							//if(hi==1){haveAns=true;rst=0;break;}
						}//含有非法字符
					}	
					if(exp[i]==')')
					{	
						if(s.size()==0){haveAns=false;break;}//表达式右括号左侧无元素 cout<<"error5"<<endl;
						mat r_matrix=s.top();s.pop();
						mat l_matrix=s.top();s.pop();
						if(l_matrix.n==r_matrix.m)
						{
							rst+=l_matrix.m*r_matrix.m*r_matrix.n;
							mat t_matrix; //t_matrix.name='@';//定义一个传递矩阵 
							t_matrix.m=l_matrix.m; 
							t_matrix.n=r_matrix.n; 
							s.push(t_matrix);
							//a[26].name='@';a[26].m=l_matrix.m;a[26].n=r_matrix.n;
							
						}else{haveAns=false;break;}//矩阵无法相乘 cout<<"error2"<<endl;
					}
				}
				if(s.size()!=1||haveAns==false)	cout<<"error"<<endl;//
				else cout<<rst<<endl; //cout<<"rst="<<rst<<endl; 
				//return s.empty();	
}

int main()
{
	int ma,ex;
	while(cin>>ma>>ex&&(ma!=0)&&(ex!=0))
	{
		//mat *a=new mat[27];
		mat a[27];
		for (int i=0;i<ma;i++)
		{
			char ch;cin>>ch;
			int index=ch-65;
			//a[index].name=ch;
			cin>>a[index].m>>a[index].n;	
		}		
			while(ex--)
			{
				string exp;
				cin>>exp;
				if(exp.size()==1)
				if(exp[0]>=65&&exp[0]<=90){cout<<0<<endl;continue;}
    			matMulCacl(exp,a);			
			}		
		//delete []a;
	}
	return 0;
}


版权声明:本文为 @iCurious
的原创文章,可以转载,但请务必注明作者和出处!!!
原文链接:|blog.csdn.net/icurious|www.blankspace.cn|www.cnblogs.com/icurious/|

原文地址:https://www.cnblogs.com/icurious/p/6082412.html