とりあえず、解けたところまで。。。
コンテスト中に解けない問題はeditorialみても解けませんっすわ。。。
A問題
- 最初の1文字を出力する
private void solveA() {
String s = next();
out.println(s.charAt(0));
}
B問題
- 「先頭の文字を末尾に移動する」という操作を$K回$行った結果
- この手の問題、きちんとローテすると絶対時間足りないんで
- ローテしたかの様に、
後ろに文字を足していく
- 生成できた文字列のk番目から元の文字の長さを切り出す
- ローテしたかの様に、
入力例2:
JKrolling
99
生成後文字列(ここの99番目から108番目までを切り出して出力)
JKrollingJKrollingJKrollingJKrollingJKrollingJKrollingJKrollingJKrollingJKrollingJKrollingJKrollingJKrolling
private void solveB() {
String s = next();
int k = nextInt();
List<String> wk = new ArrayList<String>();
for (int i = 0; i < s.length(); i++) {
wk.add(s.substring(i, i + 1));
}
for (int i = 0; i < k; i++) {
wk.add(wk.get(i));
// wk.remove(0);
}
StringBuilder builder = new StringBuilder();
for (int i = k; i < wk.size(); i++) {
builder.append(wk.get(i));
}
out.println(builder.toString());
}
C問題
- 7日前から当日までというのに注意
private void solveC() {
int numN = nextInt();
int start = numN - 7;
for (int i = start; i <= numN; i++) {
out.println(i);
}
}
D問題
- 最善の手段なので
- 入力値をソートして
- 後ろから、
高橋 -> 青木
の順で取っていく
- 後ろから、
- 入力値をソートして
private void solveD() {
int n = nextInt();
int x = nextInt();
int y = nextInt();
int[] wk = IntStream.range(0, n).map(i -> nextInt()).toArray();
Arrays.sort(wk);
int tak = 0;
int aok = 0;
for (int i = 0; i < wk.length; i++) {
if ((i & 1) == 1) {
aok += wk[wk.length - 1 - i];
} else {
tak += wk[wk.length - 1 - i];
}
}
tak += x;
aok += y;
if (aok > tak) {
out.println("Aoki");
} else if (aok < tak) {
out.println("Takahashi");
} else {
out.println("Draw");
}
}
E問題
-
TLEになったので書き直したversion
-
1日もデートに行かない場合は$精進可能日-精進可能日/休暇$で精進日がわかる
-
記念日が0日、1日は分岐
-
記念日2日以上のループの最終日は分岐
- 通常の処理に加え、最後の記念から最終日までの処理を追加
private void solveE() {
long n = nextLong();
long a = nextLong();
long b = nextLong();
List<Long> day = new ArrayList<Long>();
for (int i = 0; i < b; i++) {
day.add(nextLong());
}
long res = 0;
/*
* 一日も記念日がない
*/
if (day.size() == 0) {
long d = n - 1;
long val = d - d / a;
res += val;
out.println(res);
return;
}
/*
* 1日だけ記念日
*/
if (day.size() == 1) {
long d = 0;
long val = 0;
d = day.get(0) - 1;
val = d - d / a;
res += val;
d = n - day.get(0);
val = d - d / a;
res += val;
out.println(res);
return;
}
Collections.sort(day);
long d = 0;
for (int wkCnt = 0; wkCnt <= n; wkCnt++) {
if (wkCnt == day.size() - 1) {
/*
* 最終の時は、
* ・休日の処理
* ・最後の日(n)から最後の休日までの処理
* の二つを実施
*/
d = day.get(wkCnt) - day.get(wkCnt - 1) - 1;
long val = d - d / a;
res += val;
d = n - day.get(wkCnt);
val = d - d / a;
res += val;
break;
} else if (wkCnt == 0) {
/*
* 最初は
*/
d = (day.get(wkCnt) - 1);
} else if (wkCnt < day.size() - 1) {
/*
* 休日の真ん中のみ取得するため、
* 次の休日-今回の休日 のあと、追加で-1
*/
d = day.get(wkCnt) - day.get(wkCnt - 1) - 1;
}
/*
* d/aがa周期の休日
*/
long val = d - d / a;
res += val;
}
out.println(res);
}
E問題:TLE
愚直に実装したけど、まぁTLE
- デート日をsetに詰めておく
- 毎日以下の判定を行う
- 記念日かどうか
- 記念日だった場合、連続日数のカウントをリセット
- デート日かどうか
- デート日の場合、連続日数のカウントをリセット
- 精進したかどうか
- 精進したらres++
- 記念日かどうか
/**
* TLE
*/
private void solveE2() {
long n = nextLong();
long a = nextLong();
long b = nextLong();
Set<Long> day = new HashSet<Long>();
for (int i = 0; i < b; i++) {
day.add(nextLong());
}
// StringBuilder builder = new StringBuilder();
long dayCnt = 0;
long res = 0;
// List<Long> add = new ArrayList<Long>();
long cnt = 1;
while (cnt <= n) {
dayCnt++;
if (dayCnt == a) {
dayCnt = 0;
// builder.append("D");
} else if (day.contains(cnt)) {
dayCnt = 0;
// builder.append("D");
} else {
res++;
// add.add(i);
// builder.append("P");
}
cnt++;
}
out.println(res);
}
F問題
- 素因数分解
- kと同じならソートしてそのまま出力
- kより小さいなら-1
- kより大きいなら、k番目以降の値を全て乗算して1つにまとめる
private void solveF() {
long n = nextLong();
long k = nextLong();
List<Integer> wk = new ArrayList<Integer>();
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
wk.add(i);
n /= i;
}
}
StringBuilder builder = new StringBuilder();
if (wk.size() == k) {
for (Integer integer : wk) {
builder.append(integer + " ");
}
} else if (wk.size() < k) {
builder.append(-1);
} else {
int cnt = 1;
for (int i = 0; i < wk.size(); i++) {
if (i < k - 1) {
builder.append(wk.get(i) + " ");
} else {
cnt *= wk.get(i);
}
}
builder.append(cnt);
}
out.println(builder.toString());
}