本想会很快写出来的程序,最后总是用了很长时间。
这题开始时用链表,大数据却是段错误和内存超限。毕竟struct貌似要额外的48字节记录信息。
#include <stdio.h>
#include <malloc.h>
typedef struct node{
int v;
struct node *nx;
}ND;
int main()
{
freopen("in.txt", "r", stdin);
int k;
int x;
int c=0;
scanf("%d", &k);
ND *p=NULL, *q=NULL, *r=NULL;
r = (ND*)malloc(sizeof(ND));
r->v = -1;
r->nx = NULL;
p = r;
while(1){
scanf("%d", &x);
if(x < 0) break;
if(c < k){
q = (ND*)malloc(sizeof(ND));
}
else{
q = p->nx;
p->nx = q->nx;
// free(q);
}
q->v = x;
q->nx = NULL;
r->nx = q;
r = q;
c++;
}
if(c < k)
printf("NULL");
else
printf("%d", p->nx->v);
return 0;
}
上面能保证链表长度不超过k,也不用free了。
考虑错误的原因一个是struct问题,另一个可能是OJ问题,因为自己做的10^8都没有段错误。不过之前用free不会有3号测试点的段错误。为什么呢?
补充1:
终于找到原因了,没放弃。
while(1){
scanf("%d", &x);
if(x < 0) break;
q = (ND*)malloc(sizeof(ND));
q->v = x;
q->nx = NULL;
r->nx = q;
r = q;
c++;
if(c > k){
q = p->nx;
p->nx = q->nx;
free(q);
}
}
之前版本的用free,没想到这几次内存都在31300+,恰好全过了。
突然发现测试点3的内存只用了256,和点1,点2一样。但3出现段错误,想到可能是k=1出错的。测试了一下,果然!
还是想了好久,最后gdb才知道是一个元素删除时引发的尾指针丢失问题:
else{
q = p->nx;
if(q->nx == NULL)
r = p;
p->nx = q->nx;
// free(q);
}
修改了else果然全过了!!
//
由于之前说的产生错误,不得不用简单的循环队列做。这种方法就简单明了。
#include <stdio.h>
int main()
{
freopen("in.txt", "r", stdin);
int k;
int x;
int c=0;
int *m;
int p=0;
scanf("%d", &k);
m = (int*)malloc(sizeof(int)*k);
while(1){
scanf("%d", &x);
if(x < 0) break;
m[p] = x;
p = (p+1)%k;
c++;
}
if(c < k)
printf("NULL");
else
printf("%d", m[p]);
return 0;
}
补充2:
链表算法出现的消耗超出预期的内存的原因,我的博客《malloc申请空间到底有多少 》分析了