【Java】入力を受け取るときに間違えたやつ。
以下のようなコードを書いたとする。
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int i = scan.nextInt(); double d = scan.nextDouble(); String s = scan.nextLine(); scan.close(); System.out.println("String: " + s); System.out.println("Double: " + d); System.out.println("Int: " + i); } }
入力例は以下。
1
3.14
My name is horoyoisawa.
結果は以下。
String: Double: 3.14 Int: 1
sの中身が空になる。
結構よくあるやつだ。だから一行加えてみる。
String ss = scan.nextLine(); // 追加
String s = scan.nextLine();
こうすると、
String: My name is horoyoisawa. Double: 3.14 Int: 1
となり、望んだ結果が得られる。
見ればわかるように、改行を考慮していなかったことで生まれた間違いだ。
今後気をつけたい。
【Java】if文の驚き
Javaをなぜか書き始めた。
もちろん何も知らないので、if文やfor文から入るのだが、そこでC++では通じるがJavaでは通用しない書き方を見つけたので備忘録用に書き留めておく。(おそらくめちゃくちゃあるある)
// 偶数の場合にeven、奇数の場合にはoddを出力したい。 int n; if(n % 2) System.out.println("odd"); else System.out.println("even");
これだとincompatible typeとなる。
required: boolean
fount: int
Javaではこのような適当な書き方は許してくれないらしい。
以下修正。
// 修正 int n; if(n % 2 == 1) System.out.println("odd"); else System.out.println("even");
B問題の最後のテストケースわからん。
after contestって名前がついてるから、おそらくコンテスト後に追加されたケースなんやろな。
今解決できんから、メモ残しとく。
AtCoder Beginner Contest 006 D - トランプ挿入ソート 誤答コード
問題
コード
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
int ans = 0;
cin >> n;
vector<int> c(n);
set<int> s;
for(int i=0;i<n;i++) cin >> c[i];
for(int i=0;i<n;i++) {
if(i == 0) s.emplace(c[i]);
else {
if(*s.rbegin() > c[i]) ans++;
s.emplace(c[i]);
}
}
cout << ans << endl;
}
素朴すぎたか。
AtCoder Beginner Contest 100 D - Patisserie ABC 誤答コード
問題
誤答コード
#include <bits/stdc++.h>
#define chmax(x, y) x = max(x, y);
using namespace std;
using P = pair<int, int>;
bool c1 (vector<long long> &a, vector<long long> &b) {
return a[0] > b[0];
}
bool c2 (vector<long long> &a, vector<long long> &b) {
return a[0] < b[0];
}
bool c3 (vector<long long> &a, vector<long long> &b) {
return a[1] > b[0];
}
bool c4 (vector<long long> &a, vector<long long> &b) {
return a[1] < b[1];
}
bool c5 (vector<long long> &a, vector<long long> &b) {
return a[2] > b[2];
}
bool c6 (vector<long long> &a, vector<long long> &b) {
return a[2] < b[2];
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<long long>> in(n, vector<long long>(3)), v1, v2, v3, v4, v5, v6;
for(int i=0;i<n;i++) for(int j=0;j<3;j++) cin >> in[i][j];
v1.assign(in.begin(), in.end());
v2.assign(in.begin(), in.end());
v3.assign(in.begin(), in.end());
v4.assign(in.begin(), in.end());
v5.assign(in.begin(), in.end());
v6.assign(in.begin(), in.end());
sort(v1.begin(), v1.end(), c1);
sort(v2.begin(), v2.end(), c2);
sort(v3.begin(), v3.end(), c3);
sort(v4.begin(), v4.end(), c4);
sort(v5.begin(), v5.end(), c5);
sort(v6.begin(), v6.end(), c6);
vector<vector<vector<long long>> *> vec(6);
vec[0] = &v1;
vec[1] = &v2;
vec[2] = &v3;
vec[3] = &v4;
vec[4] = &v5;
vec[5] = &v6;
vector<vector<long long>> ans(6, vector<long long>(3));
for(int i=0;i<m;i++) {
for(int j=0;j<6;j++) {
for(int k=0;k<3;k++) {
ans[j][k] += (*vec[j])[i][k];
}
}
}
long long result = -1;
for(int i=0;i<6;i++) {
chmax(result, abs(ans[i][0]) + abs(ans[i][1]) + abs(ans[i][2]));
}
cout << result << endl;
return 0;
}
提出結果
どっかでオーバーフローしているか、範囲外アクセスしているか。
ローカルで動かしてみて結果が正しいが、ジャッジにはRE(Runtime Error)と判断された時
皆さんも一度は経験があるのではないか。ローカルでは動くけど、提出してみてエラーになる問題。
今回対象にしている問題はこちら。
コードを提出した結果とそのスクショはこちら。
WAではなくREになっているのは、コードとして間違っている部分があることが多い。それを今回は発見していく。
提出コード
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k, c;
cin >> n >> k >> c;
string s;
cin >> s;
vector<int> can;
vector<int> ans;
for(int i=0;i<n;i++) {
if(s[i] == 'o') can.emplace_back(i);
}
vector<int> days(can.size());
for(int i=n-1;i>=0;i--) {
auto it = upper_bound(can.begin(), can.end(), can[i]+c);
if(it == can.end()) days[i] = 1;
else {
int j = distance(can.begin(), it);
days[i] = days[j] + 1;
}
}
if(days.front() > k) {
cout << endl;
return 0;
}
int lim = -1;;
for(int i=0;i<days.size();i++) {
if(i == 0) {
if(days[i] != days[i+1]) {
ans.emplace_back(can[i]+1);
lim = can[i] + c;
}
}
else if(i == days.size()-1) {
if(can[i-1] <= lim || days[i] != days[i-1]) {
ans.emplace_back(can[i]+1);
}
}
else if(can[i] <= lim) continue;
else if(can[i-1] <= lim) {
if(days[i] != days[i+1]) {
ans.emplace_back(can[i]+1);
lim = can[i] + c;
}
}
else {
if(days[i] != days[i-1] && days[i] != days[i+1]) {
ans.emplace_back(can[i]+1);
lim = can[i] + c;
}
}
}
if(!ans.size()) cout << endl;
else for(auto& el : ans) cout << el << endl;
return 0;
}
#include <bits/stdc++.h> using namespace std; int main() { int n, k, c; cin >> n >> k >> c; string s; cin >> s; vector<int> can; vector<int> ans; for(int i=0;i<n;i++) { if(s[i] == 'o') can.emplace_back(i); } vector<int> days(can.size()); for(int i=n-1;i>=0;i--) { auto it = upper_bound(can.begin(), can.end(), can[i]+c); if(it == can.end()) days[i] = 1; else { int j = distance(can.begin(), it); days[i] = days[j] + 1; } } if(days.front() > k) { cout << endl; return 0; } int lim = -1;; for(int i=0;i<days.size();i++) { if(i == 0) { if(days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } else if(i == days.size()-1) { if(can[i-1] <= lim || days[i] != days[i-1]) { ans.emplace_back(can[i]+1); } } else if(can[i] <= lim) continue; else if(can[i-1] <= lim) { if(days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } else { if(days[i] != days[i-1] && days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } } if(!ans.size()) cout << endl; else for(auto& el : ans) cout << el << endl; return 0; }
#include <bits/stdc++.h> using namespace std; int main() { int n, k, c; cin >> n >> k >> c; string s; cin >> s; vector<int> can; vector<int> ans; for(int i=0;i<n;i++) { if(s[i] == 'o') can.emplace_back(i); } vector<int> days(can.size()); for(int i=n-1;i>=0;i--) { auto it = upper_bound(can.begin(), can.end(), can[i]+c); if(it == can.end()) days[i] = 1; else { int j = distance(can.begin(), it); days[i] = days[j] + 1; } } if(days.front() > k) { cout << endl; return 0; } int lim = -1;; for(int i=0;i<days.size();i++) { if(i == 0) { if(days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } else if(i == days.size()-1) { if(can[i-1] <= lim || days[i] != days[i-1]) { ans.emplace_back(can[i]+1); } } else if(can[i] <= lim) continue; else if(can[i-1] <= lim) { if(days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } else { if(days[i] != days[i-1] && days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } } if(!ans.size()) cout << endl; else for(auto& el : ans) cout << el << endl; return 0; }
#include <bits/stdc++.h> using namespace std; int main() { int n, k, c; cin >> n >> k >> c; string s; cin >> s; vector<int> can; vector<int> ans; for(int i=0;i<n;i++) { if(s[i] == 'o') can.emplace_back(i); } vector<int> days(can.size()); for(int i=n-1;i>=0;i--) { auto it = upper_bound(can.begin(), can.end(), can[i]+c); if(it == can.end()) days[i] = 1; else { int j = distance(can.begin(), it); days[i] = days[j] + 1; } } if(days.front() > k) { cout << endl; return 0; } int lim = -1;; for(int i=0;i<days.size();i++) { if(i == 0) { if(days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } else if(i == days.size()-1) { if(can[i-1] <= lim || days[i] != days[i-1]) { ans.emplace_back(can[i]+1); } } else if(can[i] <= lim) continue; else if(can[i-1] <= lim) { if(days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } else { if(days[i] != days[i-1] && days[i] != days[i+1]) { ans.emplace_back(can[i]+1); lim = can[i] + c; } } } if(!ans.size()) cout << endl; else for(auto& el : ans) cout << el << endl; return 0; }
疑うべきは配列の範囲外アクセスですよね!
となって発見できるのが、vector<int> daysの下のiの部分。nはもとも文字列sの長さであってdaysの長さではない。ここをdays.size()に直す。
そして提出した結果がこちら。
これで自分の解き方が間違っていることが大体わかった。あとはどこが間違っていたのかを考える段階。
これのどこが間違っていたのかに関しては別のノートでまとめようか。
では。