1012 The Best Rank

本文介绍了一种用于评估计算机科学专业一年级学生在三门课程(C编程语言、数学和英语)表现的算法。该算法不仅计算学生的课程排名,还确定每个学生在所有课程及平均成绩中的最佳排名,并强调最高优先级的排名。

1012 The Best Rank (25 分)

To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algrbra), and E - English. At the mean time, we encourage students by emphasizing on their best ranks -- that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.

For example, The grades of CME and A - Average of 4 students are given as the following:

StudentID  C  M  E  A
310101     98 85 88 90
310102     70 95 88 84
310103     82 87 94 88
310104     91 91 91 91

Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M(≤2000), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of CM and E. Then there are M lines, each containing a student ID.

Output Specification:

For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.

The priorities of the ranking methods are ordered as A > C > M > E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.

If a student is not on the grading list, simply output N/A.

Sample Input:

5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999

Sample Output:

1 C
1 M
1 E
1 A
3 A
N/A


题型分类:排序、map

题目大意:对给定成绩的学生进行排序,对给定查询的学生序号,查询其最好的排名和对应的科目。

解题思路:使用sort函数进行排序,值得注意的是,这里题目中给定的学生编号是a string of 6 digits,虽然题目中的输入都是数字,但是我感觉是不严谨的,最好使用字符串,但这也增大了代码量。下面两种解法都给出,使用string的解法个人感觉较为严谨,虽然使用数组的解法代码更短也能通过。


解法一(使用map来输出):

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>

using namespace std;

const int maxn = 2010;
const int INF = 0x3f3f3f3f;
char subject[4] = {'A', 'C', 'M', 'E'};

typedef struct student{
	string id;
	int grade[4]; //grade依次存放A、C、M、E的成绩 
	int rank;
	student(){
		memset(grade, 0, sizeof(grade));
	}
}student;

typedef struct result{
	int rank;
	int sub; 
	result(){
		rank = INF;
		sub = -1;
	}
}result;

student stu[maxn];
map<string, result> mp; //存储最好的排名和对应的科目 
int order; //表示用哪个成绩进行排序 

bool cmp(student stu1, student stu2);

int main(int argc, char** argv) {
	int N, M;
	scanf("%d %d", &N, &M);
	for(int i = 0; i < N; i++){
		cin >> stu[i].id;
		for(int j = 1; j <= 3; j++){
			cin >> stu[i].grade[j];
			stu[i].grade[0] += stu[i].grade[j]; //平均数直接使用和来保存,避免了小数点的麻烦 
		}
	}
	for(order = 0; order < 4; order++){ //order表示分别是用哪个成绩进行排序 
		sort(stu, stu + N, cmp);
		for(int i = 0; i < N; i++){
			if(i == 0 || stu[i].grade[order] != stu[i - 1].grade[order]){
				stu[i].rank = i + 1;
			}else{
				stu[i].rank = stu[i - 1].rank;
			}
			if(stu[i].rank < mp[stu[i].id].rank){
				mp[stu[i].id].rank = stu[i].rank;
				mp[stu[i].id].sub = order;
			}
		}
	}
	for(int i = 0; i < M; i++){
		string query;
		cin >> query;
		if(mp[query].sub == -1){ //sub在构造函数里初值是-1,此时表示数据没有录入,即N/A 
			cout << "N/A" << endl;
		}else{
			cout << mp[query].rank << " " << subject[mp[query].sub] << endl;
		}
	}
	return 0;
}

bool cmp(student stu1, student stu2){
	return stu1.grade[order] > stu2.grade[order];
}

解法二(使用数组来输出,即假定学生的编号只有数字没有字符):

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 2010;
const int INF = 0x3f3f3f3f;

char C[4] = {'A', 'C', 'M', 'E'};

typedef struct student {
	int id;
	int grade[4];
	student() {
		memset(grade, 0, sizeof(grade));
	}
} student;

student stu[maxn];
int Rank[1000010][4];
int order;

bool cmp(student a, student b);

int main(int argc, char** argv) {
	int N, M;
	scanf("%d %d", &N, &M);
	for(int i = 0; i < N; i++) {
		scanf("%d", &stu[i].id);
		for(int j = 1; j <= 3; j++) {
			scanf("%d", &stu[i].grade[j]);
			stu[i].grade[0] += stu[i].grade[j];
		}
	}
	for(order = 0; order < 4; order++) {
		sort(stu, stu + N, cmp);
		for(int i = 0; i < N; i++) {
			if(i == 0 || stu[i].grade[order] != stu[i - 1].grade[order]) {
				Rank[stu[i].id][order] = i + 1;
			} else {
				Rank[stu[i].id][order] = Rank[stu[i - 1].id][order];
			}
		}
	}
	for(int i = 0; i < M; i++) {
		int query;
		scanf("%d", &query);
		int bestRank = INF, bestCourse = -1;
		for(order = 0; order < 4; order++) {
			if(Rank[query][order] < bestRank) {
				bestRank = Rank[query][order];
				bestCourse = order;
			}
		}
		if(bestRank == 0)  printf("N/A\n");
		else  printf("%d %c\n", bestRank, C[bestCourse]);
	}

	return 0;
}

bool cmp(student a, student b) {
	return a.grade[order] > b.grade[order];
}

 

<think>嗯,用户这次查询的是关于一篇特定论文的算法实现代码。从问题描述看,用户需要的是"Jacobi Algorithm for the Best Multilinear Rank Approximation of Symmetric Tensors"这篇论文的配套源码。 注意到用户使用了非常专业的术语"对称张量的最佳多线性秩逼近",这应该是高阶张量分解领域的核心问题。用户能明确提出算法名称和论文标题,说明ta对该领域有相当深入的了解,大概率是相关专业的研究生或科研人员。 查询中值得关注的细节是"bes"应为"best"的笔误,但结合上下文能明确判断用户指的是最佳逼近问题。由于张量计算领域开源资源相对稀缺,可能需要从以下几个途径帮助用户: 首先想到顶级期刊的补充材料渠道。张量分解领域的代表性论文通常会公开算法实现,比如SIAM期刊就要求作者提交可复现代码。用户提到的Jacobi算法正是对称张量分解的经典方法,作者很可能在个人主页或期刊附件中公布了MATLAB代码。 考虑到算法实现的语言偏好,这类数值计算程序多用MATLAB或Python编写。需要特别提醒用户检查论文的实验部分,通常会有"Code Availability"声明。如果期刊网站没有提供,下一步建议搜索作者所在机构的知识库,比如INRIA这类研究机构会长期维护成果存档。 用户似乎已经掌握核心理论,现在急需代码进行实验验证。除了主文献外,还可以推荐GitHub上的相关开源项目,比如TensorLab库就包含多种对称张量分解实现。不过要注意提醒用户确认算法细节是否完全对应论文版本。 最后需要管理用户预期:如果确实找不到原作者的实现,可以建议基于TensorLy等现代框架自行实现Jacobi旋转更新。这类迭代算法核心部分通常不超过200行代码,关键在高效实现正交变换。 </think>关于Jacobi算法用于对称张量最佳多线性秩逼近的源代码,建议通过以下途径获取: ### 一、核心获取途径 1. **期刊补充材料** 该算法通常发表于数值计算/张量分析领域的顶刊(如 *SIAM Journal on Matrix Analysis*),在论文主页的"Supplementary Material"或"Software"部分查找。例如: $$ \text{若有代码} \implies \text{期刊页面会显示} \ \texttt{[Supplemental\_Code.zip]} $$ 2. **作者个人主页** 主要作者(如P. Comon, L. De Lathauwer等)的学术主页常维护代码库: ```markdown - [INRIA Galaad团队](https://team.inria.fr/galaad/software/) - [KU Leuven ESAT实验室](https://www.esat.kuleuven.be/stadius/) ``` 3. **开源社区平台** GitHub搜索关键词组合: ```bash "symmetric tensor" + "multilinear rank" + jacobi "tensor approximation" + jacobi + symmetric ``` ### 二、备选实现方案 若原始代码不可得,可参考同类权威实现: 1. **TensorLab库**(MATLAB) ```matlab % 安装后调用高阶SVD函数 addpath(genpath('tensorlab_2016')); T = randn(5,5,5); % 创建对称张量 [U, S] = mlsvd(T, [2,2,2]); % 多线性秩(2,2,2)逼近 ``` 2. **TensorLy库**(Python) ```python from tensorly.decomposition import tucker import tensorly as tl # 生成对称张量(需自定义对称化处理) tensor = tl.tensor(...) core, factors = tucker(tensor, rank=(2,2,2), init='random') ``` ### 三、关键算法实现要点 Jacobi法的核心迭代步骤(伪代码): ```python def jacobi_rotation(A, rank, max_iter=100): # A: 对称三阶张量 for dim in range(3): # 三个模态循环 U = initialize_orthogonal_matrix(rank[dim]) for _ in range(max_iter): # 计算Givens旋转角度(关键步骤) theta = compute_optimal_angle(A, U) # 更新正交变换矩阵 U = apply_givens_rotation(U, theta) # 更新张量核心 A = update_core_tensor(A, U, dim) return A, [U1, U2, U3] # 返回核心张量和因子矩阵 ``` > 注:完整实现需处理对称性约束($A_{ijk} = A_{\sigma(ijk)}, \forall \sigma$)和正交化[^1] ### 四、推荐替代资源 1. **[Tensor Toolbox](https://www.tensortoolbox.org/)**:含对称张量分解模块(MATLAB) 2. **[TensorKit.jl](https://jutho.github.io/TensorKit.jl/stable/)**:Julia实现的张量运算库,支持对称约束 3. **[论文复现项目](https://github.com/AndiH/tensor-decompositions)**:社区实现的经典算法集合
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值