問題リンク:
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;
}