pat 1074

本文介绍了一种链表逆置算法的实现方法,通过给定的K值,逆置链表中的每K个元素。文章详细解释了算法流程,并提供了代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1074. Reversing Linked List (25)

时间限制
300 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K = 3, then you must output 3→2→1→6→5→4; if K = 4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (<= 105) which is the total number of nodes, and a positive K (<=N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, andNext is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000

99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include <stdio.h>
#include <string.h>

struct Node
{
	int next;
	int data;
	int cur;
} node[100010];

Node nd[100010]; //我靠,靠靠。刚开始的时候有一个测试点没过,耗费了半天找错误。最后竟然是把nd数组的大小写成了10010,中间少见了个0。。。

int start, n, k;

int main()
{
	int i, tmp, j;

	while(scanf("%d %d %d", &start, &n, &k) != EOF)
	{
		for(i = 1; i <= n; i++)
		{
			scanf("%d", &tmp);
			scanf("%d%d", &node[tmp].data, &node[tmp].next);
			node[tmp].cur = tmp;
		}

		tmp = start;
		i = 1;

		while(tmp != -1)
		{
			nd[i] = node[tmp];
			tmp = node[tmp].next;
			i++;
		}

		n = i - 1; //n是去除链表中多余的结点后的长度

		if(k > n) //如果要逆置的元素个数大于链表的长度
		{
			for(i = n; i >= 1; i--)
			{
				printf("%05d %d", nd[i].cur, nd[i].data);
				if(i != 1)
					printf(" %05d\n", nd[i-1].cur);
				else
					printf(" -1\n");
			}
			continue;
		}

		memset(node, -1, sizeof(node));

		int cnt = 1;
		i = 1;

		while(k * cnt <= n)
		{
			int end = k * cnt, begin = end - k + 1;
		
			for(; end >= begin; end--)
			{
				node[i].cur = nd[end].cur;
				node[i].data = nd[end].data;
				i++;
			}
			cnt++;
		}

		cnt--;

		for(j = cnt * k + 1; j <= n; j++)
			node[i++] = nd[j];

		for(j = 1; j < i; j++)
		{
			printf("%05d %d", node[j].cur, node[j].data);

			if(j < i-1)
				printf(" %05d\n", node[j+1].cur);
			else if(j == i-1)
				printf(" -1\n");
		}
	}
	return 0;
}




<think>好的,我需要处理用户关于PAT乙级考试中C语言题目1074的请求。首先,用户希望得到这个题目的解析、解题方法和代码示例。根据用户提供的引用内容,我需要检查是否有提到题目1074的信息。查看引用1到4,发现引用1是关于1001题的解析,引用2是考试经验,引用3是1040题的代码,引用4是1003题的解法。看起来这些引用中没有直接涉及1074题的内容。 因此,我需要依靠自己的知识库来回答这个问题。首先,我需要回忆PAT乙级1074题的具体内容。题目1074通常涉及字符串处理或者进制转换,因为PAT乙级中的这类题目较多。例如,可能涉及宇宙无敌加法器的题目,即实现特定进制下的加法运算。 接下来,我需要确定题目的具体要求。题目1074通常描述的是两个数按照给定的每位数字的进制进行相加。例如,每位数字的进制可能不是固定的,而是由输入指定的,比如个位是十进制,十位是八进制,百位是二进制等等。需要将两个数按位相加,并处理进位问题。 解题思路应该是这样的:首先读取输入的进制规则,然后读取两个需要相加的数。将两个数转换为字符串,对齐位数,不足的前面补零。然后从低位到高位逐位相加,考虑进位。需要注意的是,如果最高位相加后还有进位,需要添加新的最高位。 在实现时,需要注意处理字符串的操作,包括反转字符串以便从低位开始处理,补零对齐长度。对于每一位的加法,要使用对应的进制,同时加上进位值。最后,结果要去掉前导零,但如果结果全为零,需要保留一个零。 代码示例方面,应该用C语言编写。首先读取进制数组,然后读取两个数字字符串。反转字符串,补零到相同长度。逐位处理加法,存储结果,最后处理进位和输出。需要特别处理前导零的情况。 在编写过程中,需要确保代码的正确性,比如进制的处理是否正确,进位是否在每一步都更新,以及结果字符串的反转和输出是否正确。此外,还要测试边界情况,例如两个数长度不一致,最高位进位等。 最后,生成相关问题,帮助用户进一步理解相关知识点,比如进制转换、字符串处理、大数运算等。</think>### PAT乙级题目1074解析:宇宙无敌加法器 #### 问题分析 题目要求实现一个"宇宙无敌加法器",即根据给定的每位数字的进制规则(例如:个位用十进制、十位用八进制),对两个数字进行加法运算。核心难点在于: 1. 按位处理不同进制规则 2. 处理不同位数数字的相加 3. 进位机制的特殊处理 #### 解题思路 1. **输入处理**: - 读取31位的进制规则字符串(每位表示对应数位的进制) - 读取两个加数字符串 2. **数据预处理**: - 反转所有字符串方便从低位开始计算 - 补零对齐字符串长度 3. **逐位相加**: - 每位计算时,使用对应位置的进制 - 处理进位值 4. **结果处理**: - 处理最高位的进位 - 去除前导零 - 处理全零的特殊情况 #### 代码实现 ```c #include <stdio.h> #include <string.h> void reverse(char *str) { int len = strlen(str); for (int i = 0; i < len/2; i++) { char temp = str[i]; str[i] = str[len-1-i]; str[len-1-i] = temp; } } int main() { char system[32], num1[22], num2[22]; scanf("%s %s %s", system, num1, num2); // 反转字符串以便从低位开始处理 reverse(system); reverse(num1); reverse(num2); int len = strlen(system); int max_len = len; // 补零对齐 while (strlen(num1) < len) strcat(num1, "0"); while (strlen(num2) < len) strcat(num2, "0"); char result[32] = {0}; int carry = 0; for (int i = 0; i < max_len; i++) { int base = system[i] == '0' ? 10 : system[i] - '0'; int sum = (num1[i] - '0') + (num2[i] - '0') + carry; carry = sum / base; result[i] = sum % base + '0'; } if (carry > 0) { result[max_len] = carry + '0'; max_len++; } // 反转结果并处理前导零 reverse(result); int start = 0; while (start < max_len-1 && result[start] == '0') start++; printf("%s\n", result + start); return 0; } ``` #### 测试点分析 1. **基本功能测试**: - 不同位数的数字相加 - 不同进制混合计算 2. **边界条件测试**: - 最高位产生进位(如999+1在十进制下) - 输入全零的情况 3. **特殊进制测试**: - 某位进制为1的特殊处理(虽然题目中规定进制范围是2-10) - 不同位使用不同进制 #### 注意事项 1. **反转处理**:所有字符串都需要先反转才能正确对应数位 2. **补零操作**:必须对齐长度,否则会导致错位计算 3. **进制处理**:注意题目中0在进制中的特殊表示(表示十进制) 4. **输出处理**:结果需要去除前导零,但至少要保留一个零
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值