题目概述:
模拟oj的排名系统,有N道题,每次没有ac的提交罚时M
每人的每道题有几个状态:0,没有提交过;负数-num,该题尚未ac并已提交num次;正数num,该题首次提交便ac,至此用时num;正数num1和括号内正数的num2,该题在第1+num2次提交时ac,至此用时num1
排名时,ac数不同时ac数降序,否则罚时不同时按罚时升序,再否则按用户名字典序升序
输入:
第一行N,M,其后若干行,每行一个字符串name和N个状态
数据只有一组,到EOF为止
限制:
1<=N<=12;10<=M<=20;用户名字符串长度<=10;提交次数<100;ac用时<1000
输出:
按名次升序输出,每行一个字符串,两个空格和两个整数,字符串占10字符,左对齐,为用户姓名,一个空格,第一个整数占2字符,右对齐,为ac数,另一个空格,第二个整数占4字符,右对齐,为罚时
样例输入:
8 20
Smith -1 -16 8 0 0 120 39 0
John 116 -2 11 0 0 82 55(1) 0
Josephus 72(3) 126 10 -3 0 47 21(2) -2
Bush 0 -1 -8 0 0 0 0 0
Alice -2 67(2) 13 -1 0 133 79(1) -1
Bob 0 0 57(5) 0 0 168 -7 0
样例输出:
Josephus 5 376
John 4 284
Alice 4 352
Smith 3 167
Bob 2 325
Bush 0 0
讨论:
水题,真正的水题,额甚至找不到匹配的知识点,不过突然有种毕业了的感觉
这里ungetc可能是个新物,可以把字符退会某个流中,有时候可以用来窥测一个流
题解状态:
0MS,1712K,1108 B,C++
#include<algorithm>
#include<string.h>
using namespace std;
#define INF 0x3f3f3f3f
#define maxx(a,b) ((a)>(b)?(a):(b))
#define minn(a,b) ((a)<(b)?(a):(b))
#define MAXN 1007
struct item
{
char name[13];//姓名
int ac;//ac数
int pt;//罚时
inline bool operator<(item &b)
{
if (ac != b.ac)
return ac>b.ac;
else if (pt != b.pt)
return pt < b.pt;
else
return strcmp(name, b.name) == -1;
}
}items[1005];//完全不知道有多少选手,随便选的数
inline void fun(int N, int M)
{
int p = 0;//计算选手数量
for (; ~scanf("%s", items[p].name); p++) {//input//原本p是在这里声明,被抠出去了,输入到EOF为止
int num;//存状态值的数字
char c;//检测括号用单字符
for (int o = 0; o < N; o++) {//遍历所有题目
scanf("%d", &num);//input//状态值的第一个数
if (num > 0) {//0和负数都是一样的,只考虑ac的即可
items[p].ac++;
items[p].pt += num;
if ((c = getchar()) == '(') {//input//检测是否跟着一个括号
scanf("%d", &num);//input
items[p].pt += M*num;
getchar();//input
}
else
ungetc(c, stdin);//input//没有括号则把读入的字符退回去,这个步骤似乎可以省略
}
}
}
sort(items, items + p);//排序,sort比qsort实现容易一些
for (int o = 0; o < p; o++)
printf("%-10s %2d %4d\n", items[o].name, items[o].ac, items[o].pt);//output//顺手复习标准输出的格式化
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
int N, M;
scanf("%d%d", &N, &M);//input
fun(N, M);
}
EOF