我试图解决Codechef上的问题。我之前已经发布了相关内容,但完全不同。
http://www.codechef.com/problems/STEPUP#
问题的概念是确定给定的测试用例是否出现所需的情况。 期望的情况是每个顶点具有比连接到它的顶点更高的间接。 IE浏览器。如果a-> b,则F(b)应> F A)。如果给定设置不可能,则输出是不可能的。如果不是,则输出具有最大间接的顶点X的最小值F(x),使得它适用于所有其他顶点。 我还没有尝试为可能的情况打印输出。
输入格式:
第一行输入包含数字t,测试用例数。
每个测试用例包含以两个空格分隔的整数N和M开头,分别表示图中的顶点数和边数。
以下M行中的每一行包含两个空格分隔的整数,b表示从顶点a到顶点b的边。
两个顶点a和b之间可以有多条边。 例如,
2
2 2
1 2
2 1
3 2
1 2
1 3
OUTPUT应为:
IMPOSSIBLE
2
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Node{
int val;
struct Node* next;
};
int indirection[10001];//indirection[a] holds count. What vertex it holds count OF is given by list[a].val;
int main()
{
int testcases, num_vertices, num_edges, a,b,c,d,e;
scanf("%d", &testcases);
while(testcases--)
{
scanf("%d %d",&num_vertices, &num_edges);
struct Node *list[num_vertices];//array of pointers to node
int h;
struct Node * ptr;
for(h=1;h<=num_vertices;h++)
{
list[h]=(struct Node *)malloc(sizeof(struct Node));
list[h]->val=0;
}
memset(indirection,0,10001);
for(e=0;e<10001;e++)
printf("Indirection[e]=%d \n",indirection[e]);
a=1;
while(a<=num_edges)
{
printf("messge printing for the %dth time\n",a);
scanf("%d %d",&b,&c);
printf("Message recd %d \n",indirection[c]);
if(indirection[c]==0)
{
printf("entered case1\n");
list[a]->val=c;
printf("S\n");
//Segfaults here
list[a]->next->val=b;
printf("SS\n");
indirection[a]=1;
ptr=list[a]->next;
printf("SSS \n");
printf("case1\n");
}
else
{ printf("entered case2\n");
indirection[c]++;
//segfaults here if i comment out the previous one
ptr->next->val=b;
printf("case2\n");
ptr=ptr->next;
}
a++;
}
int tra,i;
struct Node *ptr1,*ptrnext;
for(i=1;i<=num_edges;i++)
{
ptr1=list[i];
ptrnext=list[i]->next;
{
if (indirection[ptr1->val]<indirection[ptrnext->val])
{ printf("IMPOSSIBLE");
break;
}
else
{
ptr1=ptrnext;
ptrnext=ptrnext->next;
}
}
}
free(list);
}
}
我在评论中提到段错误的两个陈述就在(我认为)有问题的陈述之前。如果我删除第一个,第二个段错误。如果我同时删除了这两个段落,那么无论如何。
仍在努力解决这个问题,以便我可以继续推进下一个问题。谢谢!
答案 0 :(得分:2)
num_vertices
被视为基于1而不是基于
struct Node *list[num_vertices];//array of pointers to node
int h;
struct Node * ptr;
// for(h=1;h<=num_vertices;h++)
for(h=0;h<num_vertices;h++)
{
list[h]=(struct Node *)malloc(sizeof(struct Node));
list[h]->val=0;
}
next
字段未按Daniel
{
list[h]=(struct Node *)malloc(sizeof(struct Node));
list[h]->val = 0;
list[h]->next = something_maybe_NULL();
}
建议更简单的malloc()
样式
list[h] = malloc(sizeof *(list[h]));
答案 1 :(得分:1)
您的代码段错误,因为您创建了一个struct Node*
数组并为它们分配内存,但您从未设置每个next
的{{1}}指针。因此,当您尝试访问时,每个Node
的{{1}}指针只是指向内存中的随机位置和段错误。
我认为你的设计是错的。如果您正在尝试创建节点的链接列表(如下一个指针的存在所示),您根本不需要创建一个数组来保存节点。
答案 2 :(得分:1)
我分析了你的所有代码并发现了几个问题,这些问题主要表明你不理解指针
数组是0
- 基于索引的
/* if you declare, struct list[size];
* index goes from 0 ti szie - 1
*/
for (h = 1 ; h <= num_vertices ; h++)
{
您永远不会初始化node->next
指针
/* You should initialize the next node to null. */
list[h]->next = NULL;
您的memset
错误,sizeof(int) != 1
/* memset(indirection, 0, 10001); wrong */
memset(indirection, 0, 10001 * sizeof(int));
访问indirection
数组
/* this is very unsafe, you don't check c */
printf("Message recd %d \n", indirection[c]);
您取消引用node->next
而不检查NULL
/* don't dereference list[a]->next without checking .
* list[a]->next->val (wrong)
*/
next = list[a]->next;
if (next != NULL)
next->val = b;
您free
list
,它是一个数组而非指针,因此您无法在其上调用free
,但是,您应该free
其元素,因为它们是有效malloc
内存的指针
for (i = 0 ; i < num_vertices ; i++)
free(list[i]);
以下是修复此问题的代码版本,我不知道您的算法是否有效,但代码的错误至少减少了6个。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/* no need for typedef, since you declare as struct Node */
struct Node
{
int val;
struct Node* next;
};
int indirection[10001];//indirection[a] holds count. What vertex it holds count OF is given by list[a].val;
int main()
{
int testcases, num_vertices, num_edges, a, b, c;
printf("input testcase: ");
scanf("%d", &testcases);
while (testcases--)
{
printf("input testcase num_vertices and num_edges: ");
scanf("%d %d",&num_vertices, &num_edges);
int h;
struct Node *list[num_vertices]; // array of pointers to node
struct Node *ptr;
/* struct list[size];
* index goes from 0 ti szie - 1
*/
for (h = 0 ; h < num_vertices ; h++)
{
/* If this is plain C you don't need the cast (struct Node *) */
list[h] = malloc(sizeof(struct Node));
list[h]->val = 0;
/* You should initialize the next node to null. */
list[h]->next = NULL;
}
/* memset(indirection, 0, 10001); wrong */
memset(indirection, 0, 10001 * sizeof(int));
/* What, you dont believe all values are 0? */
/* for(e = 0 ; e < 10001 ; e++)
printf("Indirection[e] = %d\n",indirection[e]); */
/* arrays go from 0 ti size - 1 */
a = 0;
while (a < num_edges)
{
printf("messge printing for the %dth time\n", a);
printf("input b and c: ");
scanf("%d %d", &b, &c);
if (c < 10001)
{
/* this is very unsafe, you don't check c */
printf("Message recd %d \n", indirection[c]);
if (indirection[c]==0)
{
struct Node *next;
printf("entered case1\n");
list[a]->val = c;
printf("S\n");
// Segfaults here
/* don't dereference list[a]->next without checking . */
next = list[a]->next;
if (next != NULL)
next->val = b;
printf("SS\n");
indirection[a] = 1;
ptr = list[a]->next;
printf("SSS \n");
printf("case1\n");
}
else
{
printf("entered case2\n");
indirection[c]++;
//segfaults here if i comment out the previous one
ptr->next->val=b;
printf("case2\n");
ptr=ptr->next;
}
a++;
}
}
int i;
struct Node *ptr1, *ptrnext;
for(i = 0 ; i < num_edges ; i++) /* arrays go from 0 ti size - 1 */
{
ptr1 = list[i];
if (ptr1 != NULL)
ptrnext = ptr1->next;
if ((ptr1 != NULL) && (ptrnext != NULL))
{
if (indirection[ptr1->val] < indirection[ptrnext->val])
{
printf("IMPOSSIBLE");
break;
}
else
{
ptr1 = ptrnext;
ptrnext = ptrnext->next;
}
}
}
for (i = 0 ; i < num_vertices ; i++)
free(list[i]);
}
return 0;
}
答案 3 :(得分:0)
代码
list[a]->next->val=b;
list[a]->next
也许NULL
。 IMO,最好在解除引用之前进行NULL
检查。
中的
ptr->next
也是如此
ptr->next->val=b;
然而,在使用之前,您需要将内存分配给next
。否则,它会指向一些
未知内存位置。
另外,为什么不从<{p>中的0
开始循环
for(h=1;h<=num_vertices;h++)
旁注:请不要转换malloc()
的返回值。