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