读书人

一题简略的练习题

发布时间: 2012-11-04 10:42:42 作者: rapoo

一题简单的练习题
嗯,好吧,难的,我死,简单的,我也死。

请看题:
Time Limit: 1 secs, Memory Limit: 32 MB
Description
校歌手大奖赛中每个评委会给每个参赛选手打分,请用类描述每个选手的被评委的评分。选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。
Input
输入数据有多组,第一行为数据组数T
每组数据第一行两个正整数 n m (3 <= n,m <= 100),表示有 n 个 评 委 , m个选手。
接下来 n 行,每行 m 个正整数。每行表示一个评委给 m 个选手的分数,分数为[0,100]的整数。
Output
请将结果输出对于每组输入数据输出 m 行,每行表示一个选手的得分,结果保留 2 位小数。

开始我用STL容器中的priority_queue将各个选手的得分压进队列,然后弹出第一个(也就是最高分),然后逐个弹出加到和上,剩一个在容器里(最低分)。结果运行超过一秒,失败。
我想是在弹出队列数据的时候耗时。

然后我用vector,这回不弹了。一个循环找出最大值,并返回最大值的游标,同时得到最小值的数值,然后先erase掉最大值,再find最小值出游标,然后erase掉,最后遍历加到和。结果还是超过了一秒
我想是在erase数据的时候造成数据的移动耗时

最后我用数组100*100的数组来存储数据。遍历一次,找出第一个最大最小值的下标,然后开个循环求和。循环到标记的最大最小值就跳过,嗯,结果小于1秒了。但是是在我电脑上小于1秒,到系统机子上超时。

我已经想不出还有什么更快的方法了。下面是我的代码(第三种):
#include<iostream>
#include<time.h>
using namespace std;
void campus_singing_competition(){
int num;
cin>>num;
time_t begin=clock();
while(num--){
int n,m;
cin>>n>>m;
if(n<3||m<3||n>100||m>100)return;
int data[100][100];
for(int i(0);i<n;i++)
for(int j(0);j<m;j++)
cin>>data[j][i];
/*到此输入完毕
找出最大值和最小值的下标,在求平均的时候读取到最大最小的时候跨过*/
for(int i(0);i<m;i++){
int max(data[i][0]),min(data[i][0]),max_index(0),min_index(0);
int sum(0);
for(int j(1);j<n;j++){
if(data[i][j]>max){
max=data[i][j];
max_index=j;
}
if(data[i][j]<min){
min=data[i][j];
min_index=j;
}
}
if(max_index<min_index)swap(max_index,min_index);//最大数的下标一定靠后,否则就交换下标
int begin(0);
for(;begin<min_index;begin++){
sum+=data[i][begin];
}
for(begin=min_index+1;begin<max_index;begin++){
sum+=data[i][begin];
}
for(begin=max_index+1;begin<n;begin++){
sum+=data[i][begin];
}
cout.setf(ios::fixed);
cout.precision(2);
cout<<sum/double(n-2)<<endl;
}
cout<<(clock()-begin)/1000.0<<endl;
}
}

[解决办法]
1.OJ上输入输出数据量大的尽量用scanf printf 而不是cin cout
2.push一个数到priority_queue中复杂度o(logn) n个数o(nlogn) 原本o(n)的简单东西,你偏要搞成
o(nlogn)
3.后面你什么set没看

读书人网 >C++

热点推荐