PAT甲级 1032 Sharing (25分) 测试点5陷阱

题目

1032 Sharing


分析

suffix是后缀,题目的意思是求两个单词的公共后缀的第一个字符的地址。我看有些博客说求的是首个共用结点的地址,我觉得是不对的。
晴神/柳神的解法,是把第一个单词中出现的字母标记,然后遍历第二个单词,出现的首个标记的字母的地址,即为所求。能这样做是因为,只要遇到了某个相同的字母,后面的就一定相同,比如样例1中,只要遇到了a,那么后面的过程都是相同的:

a(00010) -> D(12345) -> i(67890) -> n(00002) -> g(00003)

所以只要遇到了第一个“相同”的字母,后面的路径就会完全一样,也就是两个单词的公共后缀,所以才可以这样做。但是什么叫“相同”?
比如样例2(没看网上博客我还没发现有两个不同地址不同next的a),出现了两个a,这好像有些不合理了,因为即使都碰到了a,但后面的走向不同不能确保相同。所以上面所说的相同,不仅仅是字母(data)相同,还必须是地址相同,比如单词1有个a(00010),单词2有个a(00011),那么这并不算在公共后缀。而上面的解法,由于不同地址的相同字母存储在不同的地方,标记也不同,所以正确运行。

举个例子:

00001 00006 5
00003 i 00004
00006 h 00003
00001 t 00002
00004 s 00005
00002 h 00003
word1(this):t->h(00002)->i->s
word2(his):h(00006)->i->s

所以公共后缀是is,而不是his


我一开始就没想到上面的做法,而是想把两个单词变成字符串形式,然后从末尾开始遍历,相同就一直递减,直到出现不相同的字符停止,输出分界处字符的地址。代码如下:

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int record[100001][2] = { 0 };

int main() {
	int addr1, addr2, n;
	cin >> addr1 >> addr2 >> n;
	for (int i = 0; i < n; i++) {
		int addr, next;
		char data;
		cin >> addr >> data >> next;
		record[addr][0] = data;
		record[addr][1] = next;
	}
	int ptr1 = addr1;
	int ptr2 = addr2;
	string word1, word2;
	vector<int> address1, address2; //为解决测试点5而加
	while (ptr1 != -1) {
		word1 += (char)record[ptr1][0];
		address1.push_back(ptr1);
		ptr1 = record[ptr1][1];
	}
	while (ptr2 != -1) {
		word2 += (char)record[ptr2][0];
		address2.push_back(ptr2);
		ptr2 = record[ptr2][1];
	}
	int i = word1.length() - 1;
	int j = word2.length() - 1;
	while (word1[i] == word2[j] && address1[i] == address2[j]/*这个条件是关键*/ && i >= 0 && j >= 0) {
		i--;
		j--;
	}
	if (i == word1.length() - 1) printf("-1");
	else printf("%05d", address1[i+1]);
}

运行时测试点5一直过不了。后来修改了最后一个while循环的条件,添加了address1[i] == address2[j],也就是说,碰到了相同字母不算,还得是相同地址的。测试点5才通过。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值