Problem:
goto busters
Problem Statement
あなたは謎のプログラムのソースコードを見つけた．
さっそくコンパイルして実行してみたが，いつまで待っても処理が終わらない．
どうやら，プログラムが無限ループしてしまっているようである．
ソースコードを詳しく見てみたところ，以下のようなことがわかった．
ソースコードは
N
行からなり，各行はラベル文か goto 文のいずれかである．
ラベル文と goto 文はそれぞれ次のようなフォーマットに従っている．
LABEL:
goto LABEL;
ここで，LABEL はラベルを表す文字列である．
プログラムは先頭の行から順番に 1 行ずつ処理される．
ラベル文と goto 文を処理したときの挙動は次のとおり：
ラベル文を処理しても何も起こらない
goto 文を処理したとき，次の処理は同じ名前のラベルを持ったラベル文から始める
最後の行を処理し終えて次に処理する行がなくなったとき，プログラムは終了する．
あなたは，いくつかの goto 文を削除することでプログラムを正しく終了させたいと思っている．
一方で，手を加える箇所はできるだけ少なくしたい．
プログラムを終了させるためには最小でいくつの goto 文を消せばいいだろうか．
Input
N
s_1
. . .
s_N
s_i
は次の二つのうちのいずれかである．
LABEL_i:
goto LABEL_i;
Constraints
1 ≦ N ≦ 100
ラベルはアルファベットの大文字または小文字のみからなる，1 文字以上 10 文字以下の文字列
すべての
s_i =
"goto LABEL_i;" に対して，
s_j =
"LABEL_i:" となる
j
が存在する．
同じ名前のラベルを持ったラベル文は二回以上現れない．
"goto" という名前のラベルは存在しない．
Output
削除すべき goto 文の最小個数を 1 行に出力せよ．
Sample Input 1
2
LOOP:
goto LOOP;
Output for the Sample Input 1
1
Sample Input 2
8
goto there;
loop:
goto loop;
here:
goto goal;
there:
goto here;
goal:
Output for the Sample Input 2
0
Sample Input 3
1
GOTO:
Output for the Sample Input 3
0

Submitted solutions:

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<functional>
#include<map>
#include<sstream>
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<int,int> P;
map<int,int> mp;
int n;
int ans;
vector<string> st;
void sec(int pos,vector<bool> used,int cnt){
  if(used[pos])
    return;
  used[pos]=true;
  if(pos==n){
    ans=min(ans,cnt);
  }else if(st[pos].substr(0,5)=="goto "){

    sec(mp[pos],used,cnt);

    sec(pos+1,used,cnt+1);
  }else{
    sec(pos+1,used,cnt);
  }
}
int main(){
  while(cin>>n){
    cin.ignore();
    st.resize(n);
    rep(i,n){
      getline(cin,st[i]);
      
    }
    rep(i,n){
      if(st[i].substr(0,5)=="goto "){
	string to=st[i].substr(5,(int)st[i].size()-6);
	rep(j,n){
	  if(to==st[j].substr(0,st[j].size()-1)){
	    mp[i]=j;
	    //cout<<i<<" "<<j<<endl;
	  }
	}
      }
    }
        
    ans=1000;
    vector<bool> used(n+1,false);
    sec(0,used,0);
    cout<<ans<<endl;
    

  }
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 1292
final_rank: 1

code_snippet: #include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string commands[100];
int ischecked[100];
int n;
int solve(int pos,int delcount)
{;
  if(pos == n)
    return delcount;
  if(ischecked[pos] == 1)
    return 10000;
  if(commands[pos].find("goto") != -1)
  {
    for(int i = 0;i<n;i++)
    {
      if(commands[i] == commands[pos].substr(5))
      {
//        cout<<"jump "<<pos<<" to "<<i<<endl;
        ischecked[pos] = 1;
        int j = solve(i+1,delcount);
        ischecked[pos] = 0;
        commands[pos] = "";
        int k = solve(pos+1,delcount+1);
        commands[pos] = "goto " + commands[i];
        return min(j,k);
      }
    }
  }
  return solve(pos+1,delcount);
}
int main(void)
{
  cin>>n;
  for(int i = 0;i<n;i++)
  {
    ischecked[i] = 0;
    string buf;
    cin>>buf;
    if(buf == "goto")
    {
      cin>>buf;
      commands[i] = "goto " + buf.substr(0,buf.length()-1);
    }else
      commands[i] = buf.substr(0,buf.length()-1);
  }
  cout<<solve(0,0)<<endl;
  return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 1244
final_rank: 2

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
 
typedef pair<int,string> P;
int n;
vector<P> v;
int pos[100],pos2[100];
vector<int> v2[100];
 
struct state{
  int n,c;
  set<int> s;
  bool operator < (const state &s) const {
    return c > s.c;
  }
};
 
void solve(){
  priority_queue<state> Q;
  state u,u2;
  set<int> s;
  bool f = false;
  u.n = u.c = 0;
  u.s = s;
 
  for(Q.push(u);!Q.empty();){
    u = Q.top();
    Q.pop();
 
    int next = u.n == n ? n : pos2[u.n];
    
    if(next < n){
      if(u.s.find(next) != u.s.end()) continue;
       
      f = false;
      if(v[next].first == 2){
        f = true;
        for(int i=0;i<v2[next].size();i++){
          if(u.s.find(v2[next][i]) == u.s.end()){
            f = false;
            break;
          }
        }
      }
 
      u2 = u;
      u2.n = next + 1;
      u2.c++;
      u2.s.insert(next);
      Q.push(u2);
 
      if(!f){
        u2 = u;
        u2.s.insert(next);
        u2.n = pos[next];
        Q.push(u2);
      }
    } else {
      cout << u.c << endl;
      return;
    }
  }
  cout << 0 << endl;
}  
 
int main(){
  string str;
  cin >> n;
  fill(pos,pos+n,-1);
  fill(pos2,pos2+n,-1);
  for(int i=0;i<n;i++){
    cin >> str;
    if(str == "goto"){
      cin >> str;
      str.erase(str.end()-1);
      v.push_back(P(1,str));
    } else{
      str.erase(str.end()-1);
      v.push_back(P(0,str));
    }
  }
 
  for(int i=0;i<n;i++){
    if(v[i].first){
      for(int j=i;j>=0;j--){
        if(pos2[j] >= 0) break;
        pos2[j] = i;
      }
      for(int j=0;j<n;j++){
        if(v[j].first == 0 && v[i].second == v[j].second){
          pos[i] = j;
          if(i > j){
            v[i].first = 2;
            for(int k=j+1;k<i;k++) if(v[k].first) v2[i].push_back(k);
          }
          break;
        }
      }
    }
  }
 
  for(int i=n-1;i>=0;i--){
    if(pos2[i] >= 0) break;
    pos2[i] = n;
  }
 
  solve();
}
accuracy: 1
time_ms: 20
memory_kb: 1960
final_rank: 2