一道PAT甲级的题目,想请大家帮忙看看我的代码

题目链接:
用了两种方法,DFS和并查集都是一样的结果,测试点0,4,5过不去,实在是不知道哪里错了 ,牛客网上能AC。请各位大神帮忙看看,万分感谢!!!

我的代码1,DFS方法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXH 17577
#define MAXP 2017

typedef struct PERSON *Person;
struct PERSON
{
    char name[4];
    int tw; // 这个人的总通话时长
};

typedef struct GANG Gang;
struct GANG
{
    int head; // 这个gang的head的哈希值
    int tm; // 这个gang的总人数
};

int N, K;
int HashTable[MAXH]; // 每个人名字的哈希表,值为这个名字对应的P的下标
int G[MAXP][MAXP]; // 图存储每两人的通话记录
Person P[MAXP]; // 存储每个人数据的数组
int p = 0; // 总人数
int tw = 0; // 当前gang的总通话时长
int tm = 0; // 当前gang的总人数
int head = -1; // 当前gang的head的名字的哈希值
Gang gang[MAXP]; // 存储每个符合条件的gang
int gnum = 0; // 满足条件的gang的总数
int entered[MAXP]; // 表示每个人是否被check过,其下标为每个人在P中的下标

int Hash(char name[])
{
    int h = 0;
    h += (name[0] - 'A') * 676 + (name[0] - 'A') * 26 + (name[0] - 'A');
    return h;
}

void DFS(int p_s)
{
    int i;

    // putchar('\n');
    // printf("$$now p_s is %s, tw is %d.$$\n", P[p_s]->name, P[p_s]->tw);
    // if (head != -1)
    // {
    //     printf("$$now the head is %s, tw is %d.$$\n", P[HashTable[head]]->name, P[HashTable[head]]->tw);
    // }
    if (head == -1 || P[p_s]->tw > P[HashTable[head]]->tw)
    {
        head = Hash(P[p_s]->name);
        // printf("$$head has been changed to %s, tw is %d.$$\n", P[HashTable[head]]->name, P[HashTable[head]]->tw);
    }
    // putchar('\n');

    for (i = 0; i < p; i++)
    {
        if (G[p_s][i])
        {
            tw += G[p_s][i];
            G[p_s][i] = 0;
            G[i][p_s] = 0;
            if (!entered[i])
            {
                tm++;
                entered[i] = 1;
                DFS(i);
            }
        }
    }
    return;
}

int compare(const void *a, const void *b)
{
    return strcmp(P[HashTable[(*((Gang *)a)).head]]->name, P[HashTable[(*((Gang *)b)).head]]->name);
}

int main()
{
    scanf("%d %d", &N, &K);
    int i, j;
    char name1[4], name2[4];
    int w;
    int h1, h2;
    int p1, p2;

    // 初始化
    for (i = 0; i < MAXP; i++)
    {
        entered[i] = 0;
        for (j = 0; j < MAXP; j++)
        {
            G[i][j] = 0;
        }
    }
    for (i = 0; i < MAXH; i++)
    {
        HashTable[i] = -1;
    }

    // 读取输入
    for (i = 0; i < N; i++)
    {
        scanf("%s %s %d", name1, name2, &w);
        h1 = Hash(name1);
        if (HashTable[h1] == -1)
        {
            // 如果name1是新名字
            P[p] = (Person)malloc(sizeof(struct PERSON));
            strcpy(P[p]->name, name1);
            P[p]->tw = w;
            HashTable[h1] = p;
            p++;
        }
        else
        {
            P[HashTable[h1]]->tw += w;
        }
        p1 = HashTable[h1];

        h2 = Hash(name2);
        if (HashTable[h2] == -1)
        {
            // 如果name2是新名字
            P[p] = (Person)malloc(sizeof(struct PERSON));
            strcpy(P[p]->name, name2);
            P[p]->tw = w;
            HashTable[h2] = p;
            p++;
        }
        else
        {
            P[HashTable[h2]]->tw += w;
        }
        p2 = HashTable[h2];

        if (!G[p1][p2])
        {
            // 需要新加一条边
            G[p2][p1] = G[p1][p2] = w;
        }
        else
        {
            G[p1][p2] += w;
            G[p2][p1] += w;
        }
    }

    // putchar('\n');
    // for (i = 0; i < p; i++)
    // {
    //     printf("$$Before DFS, %s has tw %d.$$\n", P[i]->name, P[i]->tw);
    // }
    // putchar('\n');

    for (i = 0; i < p; i++)
    {
        if (!entered[i])
        {
            tm++;
            entered[i] = 1;
            DFS(i);
            if (tm >= 3 && tw > K)
            {
                gang[gnum].tm = tm;
                gang[gnum].head = head;
                gnum++;
            }
        }
        head = -1;
        tm = 0;
        tw = 0;
    }

    qsort(gang, gnum, sizeof(gang[0]), compare);

    printf("%d\n", gnum);
    for (i = 0; i < gnum; i++)
    {
        printf("%s %d\n", P[HashTable[gang[i].head]]->name, gang[i].tm);
    }

    return 0;
}


我的代码2,并查集方法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXH 17576
#define MAXP 2017

typedef struct PERSON *Person;
struct PERSON
{
    char name[4];
    int tw; // 这个人的总通话时长
};

typedef struct GANG Gang;
struct GANG
{
    int head; // 这个gang的head在P中的下标
    int tm; // 这个gang的总人数
};

int N, K;
int HashTable[MAXH]; // 每个人名字的哈希表,值为这个名字对应的P的下标
Person P[MAXP]; // 存储每个人数据的数组
int p = 0; // 总人数
int tw = 0; // 当前gang的总通话时长
int tm = 0; // 当前gang的总人数
int head = -1; // 当前gang的head在P中的下标
Gang gang[MAXP]; // 存储每个符合条件的gang
int gnum = 0; // 满足条件的gang的总数
int set[MAXP]; // 并查集,存储父结点的下标,下标为每个人在P中的下标
int checked[MAXP];

int Hash(char name[])
{
    int h = 0;
    h += (name[0] - 'A') * 676 + (name[0] - 'A') * 26 + (name[0] - 'A');
    return h;
}

int compare(const void *a, const void *b)
{
    return strcmp(P[(*((Gang *)a)).head]->name, P[(*((Gang *)b)).head]->name);
}

int Find(int v)
{
    if (set[v] < 0)
    {
        return v;
    }
    else
    {
        return Find(set[v]);
    }
}

void CompactPath(int d, int s)
{
    // 路径压缩,将d及d所有的孩子的祖先都改成s
    int i;
    set[d] = s;
    for (i = 0; i < p && set[i] != d; i++);
    if (i < p)
    {
        CompactPath(i, s);
    }
    return;
}

void Union(int p1, int p2)
{
    int r1 = Find(p1);
    int r2 = Find(p2);
    if (r1 != r2 && set[r1] <= set[r2])
    {
        set[r1] += set[r2];
        CompactPath(r2, r1);
    }
    else if (r1 != r2 && set[r1] > set[r2])
    {
        set[r2] += set[r1];
        CompactPath(r1, r2);
    }
    return;
}

int main()
{
    scanf("%d %d", &N, &K);
    int i;
    char name1[4], name2[4];
    int w;
    int h1, h2;
    int p1, p2;

    // 初始化
    for (i = 0; i < MAXP; i++)
    {
        set[i] = -1;
        checked[i] = 0;
    }
    for (i = 0; i < MAXH; i++)
    {
        HashTable[i] = -1;
    }

    // 读取输入
    for (i = 0; i < N; i++)
    {
        scanf("%s %s %d", name1, name2, &w);
        h1 = Hash(name1);
        if (HashTable[h1] == -1)
        {
            // 如果name1是新名字
            P[p] = (Person)malloc(sizeof(struct PERSON));
            strcpy(P[p]->name, name1);
            P[p]->tw = w;
            HashTable[h1] = p;
            p++;
        }
        else
        {
            P[HashTable[h1]]->tw += w;
        }
        p1 = HashTable[h1];

        h2 = Hash(name2);
        if (HashTable[h2] == -1)
        {
            // 如果name2是新名字
            P[p] = (Person)malloc(sizeof(struct PERSON));
            strcpy(P[p]->name, name2);
            P[p]->tw = w;
            HashTable[h2] = p;
            p++;
        }
        else
        {
            P[HashTable[h2]]->tw += w;
        }
        p2 = HashTable[h2];

        Union(p1, p2);
    }

    int j;
    for (i = 0; i < p; i++)
    {
        if (!checked[i] && set[i] <= -3)
        {
            checked[i] = 1;
            tw = P[i]->tw;
            tm = -1 * set[i];
            head = i;
            for (j = 0; j < p; j++)
            {
                if (!checked[j] && Find(j) == i)
                {
                    tw += P[j]->tw;
                    checked[j] = 1;
                    if (P[j]->tw > P[head]->tw)
                    {
                        head = j;
                    }
                }
            }
            if (tm >= 3 && tw > 2 * K)
            {
                gang[gnum].tm = tm;
                gang[gnum].head = head;
                gnum++;
            }
        }
    }


    qsort(gang, gnum, sizeof(gang[0]), compare);

    printf("%d\n", gnum);
    for (i = 0; i < gnum; i++)
    {
        printf("%s %d\n", P[gang[i].head]->name, gang[i].tm);
    }

    return 0;
}

全部评论

相关推荐

11-24 11:23
门头沟学院 C++
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-24 20:55
阿里国际 Java工程师 2.7k*16.0
程序员猪皮:没有超过3k的,不太好选。春招再看看
点赞 评论 收藏
分享
尊尼获获:闺蜜在哪?
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务