【PAT】 1129. Recommendation System 测试点一(第二个测试点)我的辛酸经历

PAT 甲1129. Recommendation System

测试点一(第二个测试点) 一直通不过,哪位大哥帮我看看55555
如果通过了,我第一时间来写题解 5555
我的解题思路如下:
1、维护一个数组Times[],Times[i]表示商品i被询问的次数,也就是输入的次数。
2、vector存放结果数组,保证每个元素在数组中都唯一出现。
3、每轮都对结果数组前k个元素中进行排序,出现的次数越多越靠前,其次就是商品编号越小越靠前。
4、每次输入都和结果数组中第K个元素进行比较,如果输入的元素优先级高于第K个元素那么就用当前输入的元素替换掉第K个元素。

#include<bits/stdc++.h>
using namespace std;
int Times[50004];
vector<int> q;
int cmp(int a, int b) {
	if (Times[a] != Times[b])
		return Times[a] > Times[b];
	else return a < b;
}
int main() {
	int N, K,temp; scanf("%d %d", &N, &K);
	for (int i = 0; i < N; i++) {
		scanf("%d", &temp);
		Times[temp]++;
		int len = q.size();
		if(Times[temp] == 1)
			q.push_back(temp);
		if(i==0) continue;
		printf("%d: %d", temp,q[0]);
		for (int i = 1; i < len && i < K; i++) 
			printf(" %d", q[i]);
		len = q.size();
		if (len > K) {
		///就是这个地方出现了问题,这个判断语句
			if ((Times[q[K - 1]] == Times[q[len - 1]] && q[len - 1] < q[K - 1]) || Times[q[len - 1]] > Times[q[K - 1]])
				q[K - 1] = q[len - 1];
			sort(q.begin(), q.begin() + K, cmp);
		}
		else
			sort(q.begin(), q.end(), cmp);
		printf("\n");
	}
}

在这里插入图片描述

有一位大哥给我提出意见:

代码这一块存在问题

if ((Times[q[K - 1]] == Times[q[len - 1]] && q[len - 1] < q[K - 1]) || Times[q[len - 1]] > Times[q[K - 1]])

其问题在于,有时候不能拿已加入的旧元素,与数组q中的第K-1个元素进行比较,比如下面的测试样例 就存在这个问题。
输入样例

13 2
5 5 6 6 7 7 8 8 1 9 9 1 1

正确输出样例为:

5: 5
6: 5
6: 5 6
7: 5 6
7: 5 6
8: 5 6
8: 5 6
1: 5 6
9: 5 6
9: 5 6
1: 5 6
1: 1 5

而我的程序输出样例为:

5: 5
6: 5
6: 5 6
7: 5 6
7: 5 6
8: 5 6
8: 5 6
1: 5 6
9: 5 6
9: 5 6
1: 5 6
1: 5 6

这是因为并不是每次输入的元素都在数组p的最后,有可能之前就存在于p中这次输入后,仅仅将该元素出现的次数+1,而不会将该元素push_back()进数组中,所以导致了上述测试样例出现错误。
所以我将q[len-1](当前数组的最后一个元素)换成了temp(当前输入的元素值)。

if (len == K && find_element(temp)) {
			if ((Times[q[K - 1]] == Times[temp] && temp < q[K - 1]) || Times[temp] > Times[q[K - 1]])
				q[K - 1] = temp;
			sort(q.begin(), q.begin() + K, cmp);
		}

这也引入了一个新的问题,就是可能在前K个元素中已经出现了当前输入的元素,temp。执行指令q[K - 1] = temp; 之后会导致前K个元素中出现两个相同的元素temp。这是不允许的所以,我还需要判断在结果素组组中前K个元素是否已经出现了temp元素。所以我就加上了一个find_elememt()函数,这样就可以通过上面的那个测试案例了。

写好之后我信誓旦旦的提交了自己代码:

#include<bits/stdc++.h>
using namespace std;
int Times[50004];
vector<int> q;
int N, K, temp;
int cmp(int a, int b) {
	if (Times[a] != Times[b])
		return Times[a] > Times[b];
	else return a < b;
}
int find_element(int x) {
	for (int i = 0; i < K&&i < q.size(); i++) {
		if (q[i] == x) return 0;
	}
	return 1;
}
int main() {
#ifdef ONLINE_JUDGE
#else
	freopen("Text.txt", "r", stdin);
#endif
	scanf("%d %d", &N, &K);
	for (int i = 0; i < N; i++) {
		scanf("%d", &temp);
		Times[temp]++;
		int len = q.size();
		if (Times[temp] == 1)
			q.push_back(temp);
		if (i == 0) continue;
		printf("%d: %d", temp, q[0]);
		for (int i = 1; i < len && i < K; i++)
			printf(" %d", q[i]);
		len = q.size();
		if (len > K && find_element(temp)) {
			if ((Times[q[K - 1]] == Times[temp] && temp < q[K - 1]) || Times[temp] > Times[q[K - 1]])
				q[K - 1] = temp;
			sort(q.begin(), q.begin() + K, cmp);
		}
		else
			sort(q.begin(), q.end(), cmp);
		printf("\n");
	}
}

但是结果给了我当头一棒:
在这里插入图片描述
还是没有通过。然后我自己又琢磨琢磨,先把自己的代码简化,优化,首先发现结果数组其实加到K个就好了,然后我就结果数组的最大容量限制在了K。也就是push_back()的时候加上了一个限制(len<K)。

if (len<K&&Times[temp]==1)
			q.push_back(temp);

优化了之后,我试探性得提交了一下代码:wocao居然AC了,测试点一也过了。但是我自己还是不知道测试点一测试的是哪种特殊的数据,不知道考察的是边界检查还是啥特殊情况。(如果想通了来更新博文,也希望大佬帮帮我,救救孩子。)

看完之后点个点个赞呗~,鼓励鼓励我早点想出来。

AC代码如下:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int Times[50004];
vector<int> q;
int N, K, temp;
int cmp(int a, int b) {
	if (Times[a] != Times[b])
		return Times[a] > Times[b];
	else return a < b;
}
int find_element(int x) {
	for (int i = 0; i < K&&i < q.size(); i++) {
		if (q[i] == x) return 0;
	}
	return 1;
}
int main() {
	scanf("%d %d", &N, &K);
	for (int i = 0; i < N; i++) {
		scanf("%d", &temp);
		Times[temp]++;
		int len = q.size();
		if (len<K&&Times[temp]==1)
			q.push_back(temp);
		if (i == 0) continue;
		printf("%d: %d", temp, q[0]);
		for (int i = 1; i < len && i < K; i++)
			printf(" %d", q[i]);
		len = q.size();
		if (len == K && find_element(temp)) {
			if ((Times[q[K - 1]] == Times[temp] && temp < q[K - 1]) || Times[temp] > Times[q[K - 1]])
				q[K - 1] = temp;
			sort(q.begin(), q.begin() + K, cmp);
		}
		else
			sort(q.begin(), q.end(), cmp);
		printf("\n");
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值