問題リンク:
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;//OK、xが見つからなかったので、新しい要素をaに挿入できる
}
for (int i = 1; i <= newp; ++i)//出力...
{
printf("%d ", a[i]);
}
putchar('\n');
}
return 0;
}