質問編集履歴
1
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,301 +1,3 @@
|
|
1
|
-
|
1
|
+
自力で頑張ってみようかと思います。
|
2
2
|
|
3
|
-
任意の数列Aと、いくつかの任意の置換Pが与えられたとき、
|
4
|
-
|
5
|
-
数列AにPをそれぞれ1回以下ずつ適用した時、得られる数列のなかで辞書順で最も早いものを出力しなさい
|
6
|
-
|
7
|
-
なお、数列の長さと、置換の数は標準入力より得られるものとする
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
###
|
12
|
-
|
13
|
-
置換Pが何種類与えられるかは、その時々によって違います。よって、与えられた置換の数が多ければ多いほど得られる数列はものすごい勢いで多くなっていくと思います。
|
14
|
-
|
15
|
-
置換2種類ならば、辞書順比較しなければならないのは5種類の数列、
|
16
|
-
|
17
|
-
置換3種類ならば、辞書順比較しなければならないのは15種類の数列、
|
18
|
-
|
19
|
-
...
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
適用する置換が1つ以下なので
|
24
|
-
|
25
|
-
例えば置換P1とP2が与えられた場合、比較するのは
|
26
|
-
|
27
|
-
A
|
28
|
-
|
29
|
-
AをP1で置換したもの
|
30
|
-
|
31
|
-
AをP2で置換したもの
|
32
|
-
|
33
|
-
AをP1で置換したものをP2で置換したもの
|
34
|
-
|
35
|
-
AをP2で置換したものをP1で置換したもの
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
これをどう実装すればいいか全くわかりませんでした。
|
40
|
-
|
41
|
-
一応なんとか試行錯誤して書いたソースコードを下に示しますが
|
42
|
-
|
43
|
-
これは、与えられる置換の数を5つまでとして作ったものです
|
44
|
-
|
45
|
-
|
3
|
+
アドバイスありがとうございました。
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
###ソースコード
|
50
|
-
|
51
|
-
```java
|
52
|
-
|
53
|
-
import java.util.*;
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
public class Main {
|
58
|
-
|
59
|
-
public static void main(String[] args) throws Exception{
|
60
|
-
|
61
|
-
Scanner sc = new Scanner(System.in);
|
62
|
-
|
63
|
-
int n = Integer.parseInt(sc.nextLine());//数列の長さ取得
|
64
|
-
|
65
|
-
String[] line = sc.nextLine().split(" ",0);
|
66
|
-
|
67
|
-
int[] s = new int[n];
|
68
|
-
|
69
|
-
for(int i=0;i<n;i++){//数列A取得
|
70
|
-
|
71
|
-
s[i] = Integer.parseInt(line[i]);
|
72
|
-
|
73
|
-
}
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
int m = Integer.parseInt(sc.nextLine());//置換の数取得
|
78
|
-
|
79
|
-
int[][] p = new int[m][n];
|
80
|
-
|
81
|
-
for(int i=0;i<m;i++){
|
82
|
-
|
83
|
-
line = sc.nextLine().split(" ",0);
|
84
|
-
|
85
|
-
for(int j=0;j<n;j++){
|
86
|
-
|
87
|
-
p[i][j] = Integer.parseInt(line[j]);//置換数列取得
|
88
|
-
|
89
|
-
}
|
90
|
-
|
91
|
-
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
int[] min = new int[n];//辞書順で一番早いものを都度保持するための配列
|
96
|
-
|
97
|
-
for(int i=0;i<n;i++){
|
98
|
-
|
99
|
-
min[i] = s[i];//まずは初期の数列を保存
|
100
|
-
|
101
|
-
}
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
int[] temp;
|
106
|
-
|
107
|
-
for(int i=0;i<m;i++){
|
108
|
-
|
109
|
-
temp = chikan(s,p[i]);//適用する置換が1種類の時
|
110
|
-
|
111
|
-
tempMin(temp,min);
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
for(int j=0;j<m;j++){
|
116
|
-
|
117
|
-
if(m==1)break;
|
118
|
-
|
119
|
-
if(i==j)continue;
|
120
|
-
|
121
|
-
int[] temp2 = chikan(temp,p[j]);//適用する置換が2種類の時
|
122
|
-
|
123
|
-
tempMin(temp2,min);
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
for(int k=0;k<m;k++){
|
128
|
-
|
129
|
-
if(m==2)break;
|
130
|
-
|
131
|
-
if(j==k||i==k)continue;
|
132
|
-
|
133
|
-
int[] temp3 = chikan(temp2,p[k]);//適用する置換が3種類の時
|
134
|
-
|
135
|
-
tempMin(temp3,min);
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
for(int l=0;l<m;l++){
|
140
|
-
|
141
|
-
if(m==3)break;
|
142
|
-
|
143
|
-
if(j==l||i==l||k==l)continue;
|
144
|
-
|
145
|
-
int[] temp4 = chikan(temp3,p[l]);//適用する置換が4種類の時
|
146
|
-
|
147
|
-
tempMin(temp4,min);
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
for(int o=0;o<m;o++){
|
152
|
-
|
153
|
-
if(m==4)break;
|
154
|
-
|
155
|
-
if(j==o||i==o||k==o||l==o)continue;
|
156
|
-
|
157
|
-
int[] temp5 = chikan(temp4,p[o]);//適用する置換が5種類の時
|
158
|
-
|
159
|
-
tempMin(temp5,min);
|
160
|
-
|
161
|
-
}
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
}
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
}
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
}
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
}
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
for(int i=0;i<n;i++){
|
184
|
-
|
185
|
-
if(i!=0){
|
186
|
-
|
187
|
-
System.out.print(" ");
|
188
|
-
|
189
|
-
}
|
190
|
-
|
191
|
-
System.out.print(min[i]);
|
192
|
-
|
193
|
-
}
|
194
|
-
|
195
|
-
System.out.println("");
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
}
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
public static void tempMin(int[] temp,int[] min){//minと比較して、辞書順で早ければminを更新
|
204
|
-
|
205
|
-
for(int j=0;j<temp.length;j++){
|
206
|
-
|
207
|
-
if(temp[j]==min[j]){
|
208
|
-
|
209
|
-
continue;
|
210
|
-
|
211
|
-
}
|
212
|
-
|
213
|
-
if(temp[j]>min[j]){
|
214
|
-
|
215
|
-
break;
|
216
|
-
|
217
|
-
}
|
218
|
-
|
219
|
-
if(temp[j]<min[j]){
|
220
|
-
|
221
|
-
for(int k=0;k<temp.length;k++){
|
222
|
-
|
223
|
-
min[k]=temp[k];
|
224
|
-
|
225
|
-
}
|
226
|
-
|
227
|
-
}
|
228
|
-
|
229
|
-
}
|
230
|
-
|
231
|
-
}
|
232
|
-
|
233
|
-
public static int calc(int m){//置換の数から、最終的に得られる数列の数を計算する
|
234
|
-
|
235
|
-
int answer=0;
|
236
|
-
|
237
|
-
for(int i=1;i<=m;i++){
|
238
|
-
|
239
|
-
answer+=calcP(m,i);
|
240
|
-
|
241
|
-
}
|
242
|
-
|
243
|
-
return answer;
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
}
|
248
|
-
|
249
|
-
public static int calcP(int m,int n){//順列の計算
|
250
|
-
|
251
|
-
int answer=1;
|
252
|
-
|
253
|
-
for(int i=0;i<n;i++){
|
254
|
-
|
255
|
-
answer *= (m-i);
|
256
|
-
|
257
|
-
}
|
258
|
-
|
259
|
-
return answer;
|
260
|
-
|
261
|
-
}
|
262
|
-
|
263
|
-
public static int[] chikan(int[] s,int[] p){//sをpによって置換する
|
264
|
-
|
265
|
-
int[] t = new int[s.length];
|
266
|
-
|
267
|
-
for(int i=0;i<p.length;i++){
|
268
|
-
|
269
|
-
t[p[i]-1] = s[i];
|
270
|
-
|
271
|
-
}
|
272
|
-
|
273
|
-
return t;
|
274
|
-
|
275
|
-
}
|
276
|
-
|
277
|
-
}
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
```
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
###補足
|
286
|
-
|
287
|
-
上記は、予想外の入力の際の例外など全然行っていませんが、
|
288
|
-
|
289
|
-
そこはひとまず目をつぶってください。
|
290
|
-
|
291
|
-
見にくくてわけわからないプログラムで申し訳ありません。
|
292
|
-
|
293
|
-
本当にわからなくて、いろいろと試行錯誤していたらこんな形になってしまいました。
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
自分のあげたソースコードは無視して
|
298
|
-
|
299
|
-
解答だけでもかまいませんので
|
300
|
-
|
301
|
-
お詳しい方どうか教えていただけないでしょうか
|