回答編集履歴
5
修正
answer
CHANGED
@@ -3,4 +3,19 @@
|
|
3
3
|
積集合は「2つの配列をそれぞれソート→小さい方から比べつつ共通の数値があったら新しい配列に入れる」というような動作になります。添字の進め方に工夫が必要なので考えてみてください。
|
4
4
|
|
5
5
|
また、1~10ということがわかっているなら、ビット演算を用いることでもっと楽にできます。
|
6
|
-
0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
|
6
|
+
0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
|
7
|
+
|
8
|
+
---
|
9
|
+
追記
|
10
|
+
回答修正が迷走してしまってすみません。
|
11
|
+
「重複を消す」の例はこんな感じですね
|
12
|
+
```c
|
13
|
+
int main(void) {
|
14
|
+
int ab[20] = {1,1,2,3,3,4,5,6,7,7,7,7,7,8,8,9,9,9,9,10}; // aとbを連結してソートした配列
|
15
|
+
int or[10];
|
16
|
+
or[0] = ab[0];
|
17
|
+
for (int i=0,j=0;i<20;i++) {
|
18
|
+
if (ab[i] > or[j]) or[++j] = ab[i];
|
19
|
+
}
|
20
|
+
}
|
21
|
+
```
|
4
削除
answer
CHANGED
@@ -1,44 +1,6 @@
|
|
1
1
|
複数回あるのを除くには、ソートしてから新しい配列を用意して、元の配列の小さい方から順に、数値が大きくなったときだけ、新しい配列に数値を入れていけばいいです。
|
2
|
-
|
2
|
+
「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。
|
3
3
|
積集合は「2つの配列をそれぞれソート→小さい方から比べつつ共通の数値があったら新しい配列に入れる」というような動作になります。添字の進め方に工夫が必要なので考えてみてください。
|
4
4
|
|
5
5
|
また、1~10ということがわかっているなら、ビット演算を用いることでもっと楽にできます。
|
6
|
-
0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
|
6
|
+
0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
|
7
|
-
|
8
|
-
---
|
9
|
-
追記
|
10
|
-
|
11
|
-
やっぱり和集合も積集合と同じように「2つの配列をそれぞれソート→小さい方から順に比べ、初出の数値があれば新しい配列に追加する」という方が合わせてイメージしやすいかもしれません。
|
12
|
-
その場合「重複を削除」はあまり意識しなくていいです。
|
13
|
-
|
14
|
-
```c
|
15
|
-
int a[10] = {...}; // ソートされた配列a
|
16
|
-
int b[10] = {...}; // ソートされた配列b
|
17
|
-
int or[10] = {0}; // 和集合が入る配列or
|
18
|
-
|
19
|
-
int i = 0; // aの添字
|
20
|
-
int j = 0; // bの添字
|
21
|
-
int k = 0; // orの添字
|
22
|
-
int max = 0; // orの現在の最大値(比較用)
|
23
|
-
|
24
|
-
while (i < 10 || j < 10) {
|
25
|
-
if (a[i] > max) {
|
26
|
-
// a[i]がmaxより大きければ、orに入れる→max更新→kを+1
|
27
|
-
max = a[i];
|
28
|
-
or[k] = a[i];
|
29
|
-
k++;
|
30
|
-
} else {
|
31
|
-
//max以下ならiを+1
|
32
|
-
i++;
|
33
|
-
};
|
34
|
-
if (b[j] > max) {
|
35
|
-
max = b[j];
|
36
|
-
or[k] = b[j];
|
37
|
-
k++;
|
38
|
-
} else {
|
39
|
-
j++;
|
40
|
-
❵
|
41
|
-
};
|
42
|
-
```
|
43
|
-
|
44
|
-
試してないのでちゃんと動くかは分かりませんかイメージとしては↑です。
|
3
修正
answer
CHANGED
@@ -19,18 +19,25 @@
|
|
19
19
|
int i = 0; // aの添字
|
20
20
|
int j = 0; // bの添字
|
21
21
|
int k = 0; // orの添字
|
22
|
-
int max =
|
22
|
+
int max = 0; // orの現在の最大値(比較用)
|
23
23
|
|
24
24
|
while (i < 10 || j < 10) {
|
25
25
|
if (a[i] > max) {
|
26
|
-
// a[i]がmax
|
26
|
+
// a[i]がmaxより大きければ、orに入れる→max更新→kを+1
|
27
27
|
max = a[i];
|
28
|
-
or[k
|
28
|
+
or[k] = a[i];
|
29
|
+
k++;
|
30
|
+
} else {
|
31
|
+
//max以下ならiを+1
|
32
|
+
i++;
|
29
33
|
};
|
30
34
|
if (b[j] > max) {
|
31
35
|
max = b[j];
|
32
|
-
or[k
|
36
|
+
or[k] = b[j];
|
33
|
-
|
37
|
+
k++;
|
38
|
+
} else {
|
39
|
+
j++;
|
40
|
+
❵
|
34
41
|
};
|
35
42
|
```
|
36
43
|
|
2
修正
answer
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
int k = 0; // orの添字
|
22
22
|
int max = -1; // orの現在の最大値(比較用)
|
23
23
|
|
24
|
-
while (i < 10 || <
|
24
|
+
while (i < 10 || j < 10) {
|
25
25
|
if (a[i] > max) {
|
26
26
|
// a[i]がmax以上なら、orに入れる→max更新→kとiを+1
|
27
27
|
max = a[i];
|
1
追記
answer
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
複数回あるのを除くには、ソートしてから新しい配列を用意して、元の配列の小さい方から順に、数値が大きくなったときだけ、新しい配列に数値を入れていけばいいです。
|
2
|
-
「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。
|
2
|
+
~~「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。~~
|
3
3
|
積集合は「2つの配列をそれぞれソート→小さい方から比べつつ共通の数値があったら新しい配列に入れる」というような動作になります。添字の進め方に工夫が必要なので考えてみてください。
|
4
4
|
|
5
5
|
また、1~10ということがわかっているなら、ビット演算を用いることでもっと楽にできます。
|
6
|
-
0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
|
6
|
+
0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
|
7
|
+
|
8
|
+
---
|
9
|
+
追記
|
10
|
+
|
11
|
+
やっぱり和集合も積集合と同じように「2つの配列をそれぞれソート→小さい方から順に比べ、初出の数値があれば新しい配列に追加する」という方が合わせてイメージしやすいかもしれません。
|
12
|
+
その場合「重複を削除」はあまり意識しなくていいです。
|
13
|
+
|
14
|
+
```c
|
15
|
+
int a[10] = {...}; // ソートされた配列a
|
16
|
+
int b[10] = {...}; // ソートされた配列b
|
17
|
+
int or[10] = {0}; // 和集合が入る配列or
|
18
|
+
|
19
|
+
int i = 0; // aの添字
|
20
|
+
int j = 0; // bの添字
|
21
|
+
int k = 0; // orの添字
|
22
|
+
int max = -1; // orの現在の最大値(比較用)
|
23
|
+
|
24
|
+
while (i < 10 || < || 10) {
|
25
|
+
if (a[i] > max) {
|
26
|
+
// a[i]がmax以上なら、orに入れる→max更新→kとiを+1
|
27
|
+
max = a[i];
|
28
|
+
or[k++] = a[i++];
|
29
|
+
};
|
30
|
+
if (b[j] > max) {
|
31
|
+
max = b[j];
|
32
|
+
or[k++] = b[j++];
|
33
|
+
};
|
34
|
+
};
|
35
|
+
```
|
36
|
+
|
37
|
+
試してないのでちゃんと動くかは分かりませんかイメージとしては↑です。
|