PAT甲级 A1165 Block Reversing(相对比较另类的解法)

本文详细解析了如何通过排序解决PAT中的链表问题,介绍了使用段值和顺序标记对链表元素进行组织,然后运用cmp函数进行节点间的比较和排序的过程。适合准备PAT考试的读者学习和复习。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

最近要考pat了,正在复习甲级算法题
看了一些答主A1165的解法,不太理解,自己又写了一篇较为浅显的题解,希望大家看完能有所收获!

简单来说就是排序,将不同块段的结点赋上不同的段值,相同的段中即附上对应的先后顺序,然后排序呀~


代码如下(示例):

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
struct node{
    int id;
    int data;
    int next;
    int block=-1;
    int loc_rank=-1;
}a[100010];
bool cmp(node &a,node &b){
    if(a.block!=b.block){
        return a.block>b.block;
    }else{
        return a.loc_rank<b.loc_rank;
    }
}
int main(){
    int first,n,k,tempid,data,next;
    scanf("%d %d %d",&first,&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d %d %d",&tempid,&data,&next);
        a[tempid].id=tempid;
        a[tempid].data=data;
        a[tempid].next=next;
    }
    vector<node>ans;
    int block=1,loc_rank=1;
    for(int i=first;i!=-1;i=a[i].next,loc_rank++){
        a[i].block=block;
        a[i].loc_rank=loc_rank;
        if(loc_rank%k==0){
            loc_rank=0;
            block++;
        }
        ans.push_back(a[i]);
    }
    sort(ans.begin(),ans.end(),cmp);
    for(int i=0;i<ans.size();i++){
        if(i!=ans.size()-1){
            printf("%05d %d %05d\n",ans[i].id,ans[i].data,ans[i+1].id);
        }else{
            printf("%05d %d -1\n",ans[i].id,ans[i].data);
        }
    }
    return 0;
}

总结

pat中链表的题目一般用静态链表即可解答~谢谢各位的观看

### 关于PAT A1015的题目描述 PAT A1015 的全名是 **"Reversible Primes" (可逆素数)**,这是一道关于素数及其性质的经典算法题。该题目要求判断一个给定的整数是否是一个可逆素数。所谓可逆素数是指:如果一个正整数 \( N \) 是素数,并且它的十进制表示反转后的数字也是素数,则称其为可逆素数。 #### 题目具体要求 输入包含多组测试数据,每组测试数据给出两个整数 \( D_1 \) 和 \( B \),其中 \( D_1 \) 表示待检测的数字,\( B \) 表示基数(即 \( D_1 \) 应被解释为 \( B \)-进制下的数值)。程序需判断 \( D_1 \) 是否为其对应的 \( B \)-进制下以及反转后再转换回十进制后均为素数的情况[^2]。 --- ### 解决方案分析 为了完成此任务,可以按照如下逻辑实现: 1. 将 \( D_1 \) 从 \( B \)-进制转换到十进制; 2. 判断原始十进制值是否为素数; 3. 对应的十进制值进行反转操作; 4. 再次验证反转后的值是否仍为素数; 以下是具体的 Python 实现代码: ```python def is_prime(n): """判断n是否为素数""" if n <= 1: return False for i in range(2, int(n**0.5)+1): if n % i == 0: return False return True def reverse_number_in_base(num_str, base): """将字符串形式的num在base进制下反转并转成十进制""" reversed_num_str = num_str[::-1] decimal_value = 0 power = 0 for char in reversed(reversed_num_str): digit = int(char) if digit >= base: # 如果某一位大于等于基底,则非法 return -1 decimal_value += digit * (base ** power) power += 1 return decimal_value while True: try: d1_b_pair = input().split() d1, b = map(int, d1_b_pair) # Step 1: Convert from base-b to decimal. original_decimal = int(str(d1), b) # Check if the converted number is prime. if not is_prime(original_decimal): print("No") continue # Reverse the digits of `d1` as a string representation. reversed_d1 = str(d1)[::-1] # Convert back into its new value after reversing it under same radix system 'b'. rev_dec_val = reverse_number_in_base(reversed_d1, b) if rev_dec_val != -1 and is_prime(rev_dec_val): print("Yes") # Both conditions met. else: print("No") except EOFError: break ``` 上述代码实现了完整的功能需求,包括但不限于进制转换、素性检验和数字翻转处理等功能模块化设计。 --- ### 注意事项 - 输入中的 \( D_1 \) 可能含有前导零,在实际计算过程中需要注意去除这些无意义的部分。 - 当遇到某些位上的数值超过当前指定基数范围时,应该立即返回错误标志 `-1` 来终止进一步不必要的运算过程[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值