horoyoisawaのゴミ箱

いろいろ書きます

ローカルで動かしてみて結果が正しいが、ジャッジにはRE(Runtime Error)と判断された時

皆さんも一度は経験があるのではないか。ローカルでは動くけど、提出してみてエラーになる問題。

今回対象にしている問題はこちら。

atcoder.jp

コードを提出した結果とそのスクショはこちら。

atcoder.jp

f:id:horoyoisawa:20200406023429p:plain

提出結果

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()に直す。

そして提出した結果がこちら。

f:id:horoyoisawa:20200406024710p:plain

ACではないが、REではなくなった。

これで自分の解き方が間違っていることが大体わかった。あとはどこが間違っていたのかを考える段階。

これのどこが間違っていたのかに関しては別のノートでまとめようか。

では。