1012 The Best Rank

该系统针对计算机科学一年级学生的成绩进行排名,考虑了C语言编程、数学和英语三门课程的成绩,强调了每个学生的最佳排名,包括课程最高分和平均分。

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 C, M, E 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 NNN and M(≤2000)M (≤2000)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][0, 100][0,100]) of that student in the order of C, M 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>EA > C > M > EA>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

题解:

很难受的一道题。。代码写得很繁杂。。
题目有许多没有表述清楚的地方:平均数采用四舍五入取整;排名时若分数相同则名次相同,但下一名次应与人数相符(具体可参考PTA排名)


#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;

struct student{
    int id;
    int c,m,e,a;
    int rc,rm,re,ra;
    char tag;
};

bool cmp_c(student s1, student s2){
    return s1.c > s2.c;
}

bool cmp_m(student s1, student s2){
    return s1.m > s2.m;
}

bool cmp_e(student s1, student s2){
    return s1.e > s2.e;
}

bool cmp_a(student s1, student s2){
    return s1.a > s2.a;
}

int main()
{
    int N,M;
    cin>>N>>M;
    student s[2001];
    for(int i=0;i<N;i++){
        cin>>s[i].id>>s[i].c>>s[i].m>>s[i].e;
        s[i].a = round((s[i].c+s[i].m+s[i].e)/3.0);
    }
    sort(s,s+N,cmp_a);
    s[0].ra = 1;
    for(int i=1;i<N;i++){
        if(s[i-1].a == s[i].a){
            s[i].ra = s[i-1].ra;
        }
        else
            s[i].ra = i+1;
    }
    sort(s,s+N,cmp_c);
    s[0].rc = 1;
    for(int i=1;i<N;i++){
        if(s[i-1].c == s[i].c){
            s[i].rc = s[i-1].rc;
        }
        else
            s[i].rc = i+1;
    }
    sort(s,s+N,cmp_m);
    s[0].rm = 1;
    for(int i=1;i<N;i++){
        if(s[i-1].m == s[i].m){
            s[i].rm = s[i-1].rm;
        }
        else
            s[i].rm = i + 1;
    }
    sort(s,s+N,cmp_e);
    s[0].re = 1;
    for(int i=1;i<N;i++){
        if(s[i-1].e == s[i].e){
            s[i].re = s[i-1].re;
        }
        else
            s[i].re = i + 1;
    }
    int sid,j;
    for(int i=0;i<M;i++){
        cin>>sid;
        for(j=0;j<N;j++){
            if(s[j].id == sid){
                int best = min(min(s[j].ra,s[j].rc),min(s[j].rm,s[j].re));
                cout<<best;
                if(best == s[j].ra)
                    cout<<" A\n";
                else if(best == s[j].rc)
                    cout<<" C\n";
                else if(best == s[j].rm)
                    cout<<" M\n";
                else
                    cout<<" E\n";
                break;
            }
        }
        if(j==N)
            cout<<"N/A"<<endl;
    }
}

<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)**:社区实现的经典算法集合
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值