我试图从输入中找到不等于0的不同数字的数量.n在1-100范围内。阵列中的数字在0-600范围内。 http://codeforces.com/problemset/problem/937/A 对于这个问题,我写了一个代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
int n, count = 0, i;
scanf("%d", &n);
int ar[n], ar2[601];
memset(ar2, 0, 600 * sizeof(int));
for (i = 0; i < n; i++) {
scanf("%d ", &ar[i]);
if (ar2[ar[i]] == 0)
ar2[ar[i]] = 1;
}
for (i = 1; i < 601; i++) {
if (ar2[i] != 0)
count++;
}
printf("%d",count);
return 0;
}
对于第一个测试用例(4 1 3 3 2),它在ideone.com的gcc 6.3中输出正确答案3,但在代码强制中使用gcc 5.1输出4。
为什么会发生这种情况,我该如何防止这种情况发生? (我认为这是因为memset,但我不确定。)
答案 0 :(得分:1)
在确定n
的值之前,您正在定义一个大小为n
的数组(请注意,scanf
之后n
的值int n, count = 0, i;
int ar[n];
...
。这是未定义的行为,因此不同的编译器可能会给出不同的结果,甚至在您的机器上启动程序可能会产生不同的结果(包括崩溃)。
而不是
int n, count = 0, i;
scanf("%d", &n);
int ar[n], ar2[601] = { 0 };
写
ar2
至少应该解决格式错误的数组,并使用0
完全初始化memset
。你可以摆脱你的date.timezone
,无论如何只能初始化600个项目(而不是601个)。
答案 1 :(得分:1)
以下是问题的快速解决方案
#include <stdio.h>
int main()
{
bool seen_number_before[601] = { false };
int count = 0;
seen_number_before[0] = true;
int n;
scanf("%d", &n); // Should do error checking here
for (int i = 0; i < n; ++i) {
int v;
scanf("%d", v); // More error checking
if (!seen_number_before[v]) // Not seen it before
seen_number_before[v] = true; // Mark it as seen
++count; // Add to the count
}
}
printf("%d\n", count);
return 0;
}
}
答案 2 :(得分:0)
您的代码中存在一些错误,当未定义n时,来自[n]。 要检查错误,请尝试使用一些有用的选项进行编译:
gcc -Wall code.c -o code -g
-Wall用于全部警告,-g用于valgrind上的调试(用于检查内存泄漏和其他错误的有用工具)。
另外,我建议您正确命名代码中的每个var,这对于大量代码库有帮助。
这是我的解决方案,
#include <stdio.h>
#include <stdlib.h>
int main(){
int n, count = 0;
scanf("%d", &n);
int *a = malloc(n * sizeof(int));
int hash[600] = { 0 };
for(int i=0; i<n; i++){
scanf("%d ", &a[i]);
if(a[i] != 0){
hash[a[i]] = 1;
}
}
for(int i=0; i<600; i++){
printf("%d ", hash[i]);
if(hash[i] == 1) ++count;
}
printf("\n\n%d\n", count);
return 0;
}
它可以及时优化,只使用一个for和/或内存中创建一个int的hashset,每个int可以存储32位并执行一些按位操作,所以如果第n位为1,则计数++,否则什么都不做。