记PAT第四题

记PAT第四题

这道题就是对结构体的熟悉,结构体的基本操作。基本就是java中的对象

读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:

每个测试输入包含 1 个测试用例,格式为

第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
… … …
第 n+1 行:第 n 个学生的姓名 学号 成绩

其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。

输出格式:

对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。

输入样例:
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95

输出样例:

Mike CS991301
Joe Math990112

#include <cstdio>

/**
 读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:
每个测试输入包含 1 个测试用例,格式为

第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
  ... ... ...
第 n+1 行:第 n 个学生的姓名 学号 成绩



其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
 **/
struct Student{
    char name[15];
    char id[15];
    int score;
}temp,ans_max,ans_min;

int main(){
    int n;
    scanf("%d",&n);
    //设置初值
    ans_max.score=-1;
    ans_min.score=101;
    for(int i=0;i<n;i++){
        scanf("%s %s %d",temp.name,temp.id,&temp.score);
        if(ans_min.score>temp.score){
            //结构体可以直接赋值
            ans_min=temp;
        }
        if(ans_max.score<temp.score){
            ans_max=temp;
        }
    }
    printf("%s %s\n",ans_max.name,ans_max.id);
    printf("%s %s\n",ans_min.name,ans_min.id);
    return 0;
}

PAT第三题
要注意的就是结构体可以直接赋值,和java需要用get,set方法不同

<think>嗯,我现在需要分析用户提供的C++代码,找出其中的错误。这道PAT甲级1082目是关于数字转换的,可能类似于将数字转换为特定格式的字符串,比如中文读法。首先,我需要先理解目的具体要求,然后结合用户提供的代码来检查可能的问。 首先,用户提供的代码看起来是处理一个数字不在本位的情况,通过交换来排序,可能是类似排列或排序的问,比如求最少交换次数。但目1082实际上是关于数字转换的,比如将数字转换成中文读法,例如输入12345,输出“一万二千三百四十五”。可能用户的代码可能存在逻辑错误或边界条件处理不当的问。 接下来,我需要查看用户提供的代码。代码的大致结构是: - 使用pos数组录每个数字的位置。 - 使用left变量统计不在本位的非零数字个数。 - 通过交换0的位置来排序,并计算交换次数cnt。 但根据目1082的要求,这似乎不太相关。可能用户可能混淆了目编号,或者引用了不正确的代码。例如,用户提到的是1082,但提供的代码可能属于另一道,比如1067或类似的排序。这种情况下,代码本身可能没有问,但不符合目的实际要求。 例如,PAT甲级1082的正确目要求是将一个数字转换为中文读法,需要考虑零的处理、单位(如万、亿)的正确使用,以及中间多个零的合并等问。例如,数字1001应转换为“yi Qian ling yi”,而代码中提供的处理方式明显不符合这个逻辑,因为代码中的逻辑是关于交换排序的。 所以,可能的问在于用户提供的代码是针对其他目(如1067 Sort with Swap(0, i)),而非1082。因此,代码本身可能存在逻辑正确性,但不符合1082目的需求。因此,错误可能在于用户混淆了目编号,导致提供的代码与问不匹配。 另外,检查代码中的具体实现: 1. 初始化pos数组:录每个数字的位置,这可能用于交换操作。 2. 处理left变量,统计非零数字不在本位的个数。 3. 当0在位置0时,找到第一个不在位的k进交换,并增加cnt。 4. 当0不在位置0时,不断将0与其正确位置的数字交换,直到0回到位置0,同时减少left。 这段代码似乎是解决通过交换0和其他元素来排序数组,并计算最少交换次数的问。例如,PAT甲级1067的要求正是如此。因此,用户可能将目编号写错,导致提供的代码与问不符。 因此,用户的问可能存在的错误是: 1. 目编号错误,提供的代码属于另一道(如1067),而非1082。 2. 如果用户确实想解决1082,那么当前代码完全不相关,需要重新编写处理数字转换的逻辑。 3. 代码中的潜在错误可能包括:数组越界(pos数组的大小为100010,但输入数字可能超过范围?比如目中的N的范围是否合理?比如当N为1e5时,数组pos的大小是否足够?或者当输入数字包含0时的处理是否正确?) 但假设用户确实想询问关于该代码的问,例如在PAT甲级1067中的错误,那么需要检查该代码是否存在逻辑错误。 例如,在代码中,当处理pos[0] ==0时,需要找到一个k,此时k从1开始递增,直到找到pos[k] !=k的情况。这里可能存在一个,当所有k>=1的位置都正确时,循环可能无法正确处理,导致无限循环。但根据目描述,当所有非0元素都在正确位置时,left应该为0,循环会结束。因此,这部分可能没有问。 另一个可能的错误是在交换过程中,当交换0和k的位置时,是否更新了pos数组中的值?在代码中,swap(pos[0], pos[k]),这应该交换的是pos[0]和pos[k]的值,即交换的是0和k的位置录。这是正确的,因为当交换两个元素的位置,pos数组中的录需要更新。 但是,假设输入的数组中有重复元素,但目中的元素是否唯一?根据代码逻辑,元素是0到N-1的一个排列,所以不会有重复。因此,代码在这种情况下是正确的。 综上所述,用户的代码可能原本是正确的,但针对的是另一道目(如1067),而用户错误地将其作为1082的代码提交,导致问。因此,主要的错误可能在于目编号的混淆,或者用户提供的代码与问不匹配。</think>以下是对您提供的C++代码的分析及错误诊断: ### 代码功能定位 根据代码逻辑判断,您实现的应是**PAT甲级1067(Sort with Swap(0, i))**的解法,而非1082(数字转换)[^3]。该代码通过交换0与其他数字实现数组排序,并统计最小交换次数。 ### 核心错误分析 #### 1. 目编号与代码逻辑不符 - **错误表现**:代码实现的是排序问的最小交换次数计算,而目1082要求的是**数字转中文读法**(例如:1234 → "yi Qian er Bai san Shi si") - **修正建议**:若需解决1082,需完全重构代码,实现数字分段处理、单位转换和零值特殊规则 #### 2. 逻辑冗余问(针对1067) ```cpp while(k<N) { if(pos[k]!=k) { swap(pos[0],pos[k]); cnt++; break; } k++; } ``` - **问**:当0回到原位时,需要找第一个未归位的非零数进交换。此处`k`应从1开始递增扫描,但已通过全局变量`k=1`初始化,可能跳过部分元素 - **修正建议**:改为局部变量`for(int k=1; k<N; k++)` #### 3. 数组越界风险 ```cpp int pos[100010]; ``` - **问**:目规定N ≤ 10^5,但数组大小设为100010,当N=100000时,访问pos[100000]会导致越界 - **修正建议**:改为`int pos[100000+5]` ### 正确代码框架(针对1067) ```cpp #include <iostream> using namespace std; int main() { int N, num, cnt = 0; cin >> N; int* pos = new int[N]; // 动态内存避免栈溢出 int left = N - 1; // 非零元素未归位计数 for(int i=0; i<N; ++i){ cin >> num; pos[num] = i; if(num == i && num != 0) left--; } int k = 1; while(left > 0){ if(pos[0] == 0){ for(; k<N; ++k){ // 每次从新位置开始扫描 if(pos[k] != k){ swap(pos[0], pos[k]); cnt++; break; } } } while(pos[0] != 0){ swap(pos[0], pos[pos[0]]); cnt++; left--; } } cout << cnt; delete[] pos; return 0; } ``` ### 关键改进说明 1. **动态内存分配**:避免大数组导致的栈溢出 2. **循环扫描优化**:每次从新位置开始查找未归位元素 3. **变量作用域控制**:避免全局变量残留值影响
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值