BuringStraw

BuringStraw

ハッシュテーブルのコードを貼ります

問題リンク:
https://www.luogu.com.cn/problem/P4305

#include <stdio.h>
#include <stdlib.h>
#define MAXN 50005//データ範囲
#define MOD 400000//モジュロ、あまり大きくしないでください、さもないとメモリを超えます
int a[MAXN];//結果を保存するため

struct node
{
    struct node* next;//次の項目を指すポインタ
    int value;//このノードが保存する値
};

struct node* head[MOD];//ハッシュテーブル、一連のリンクリストから構成され、リンクリストのヘッダーポインタを保存する

void insert(struct node* p, int v)//ノードpの後にvを挿入
{
    if (p == NULL) return;//NULLに対して操作できないので、安全のため
    struct node *t = malloc(sizeof(struct node));//新しいノードのメモリを割り当て
    t -> value = v;//値を設定
    //挿入プロセス
    t -> next = p -> next;//この項目の次の項目を前の項目の次の項目に設定
    p -> next = t;//前の項目の次の項目をこの項目に設定
}

int find(struct node*p, int v)//ノードpから後ろに検索し、見つかるまでまたはリンクリストの末尾まで
{
    while(p != NULL)//NULLに到達するまで停止、最後の項目のnextはデフォルトでNULL
    {
        if (p -> value == v)//vを見つけた
        {
            return 1;//見つけたら直接ループを抜ける
        }
        p = p -> next;//前に進む
    }
    return 0;//見つからなかった場合のみループを終了する機会がある
}

int main() {
    int t;//データの組数
    scanf("%d", &t);
    while (t--)//t回だけループ
    {
        for (int i = 0; i < MOD; ++i)
        {
            head[i] = NULL;
        }
        int n;
        scanf("%d", &n);
        int newp = 0;//aの最新要素のインデックスを記録、個人的な習慣で1を最初の要素のインデックスとする
        for (int i = 1; i <= n; ++i)
        {
            int x;
            scanf("%d", &x);//数を入力
            int flag = 0;//0は同じデータがないことを示し、1はあることを示す
            int m = x % MOD;//モジュロの結果、headでインデックスを使用
            if (m < 0)//負の数のモジュロは負の数を得るため、インデックスが越える
                m = -m;
            //検索時に3つのケースに分かれる
            if (head[m] == NULL)//head[m]が指すリンクリストが存在しない
            {//最初の要素を手動で初期化
                head[m] = malloc(sizeof(struct node));//メモリを割り当て
                head[m] -> value = x;//値を設定
                head[m] -> next = NULL;//次の項目はまだない
            } else
            {//リンクリストが存在する
                if (find(head[m], x)/*xを検索*/) flag = 1;//見つけた
                else
                {//見つからなかった
                    struct node* p = head[m];//リンクリストのヘッダーポインタを取得
                    while (p -> next != NULL) p = p -> next;//尾部まで進む
                    insert(p, x);//挿入
                }
            }
            if (!flag) a[++newp] = x;//良い、xが見つからなかったので、aに新しい要素を挿入できる
        }

        for (int i = 1; i <= newp; ++i)//出力。。
        {
            printf("%d ", a[i]);
        }
        putchar('\n');
    }
    return 0;
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。