Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	distance_table := [][]int{
		{0, 6, 13, 18, 23, 43, 58},
		{6, 0, 7, 12, 17, 37, 52},
		{13, 7, 0, 5, 10, 30, 45},
		{18, 12, 5, 0, 5, 25, 40},
		{23, 17, 10, 5, 0, 20, 35},
		{43, 37, 30, 25, 20, 0, 15},
		{58, 52, 45, 40, 35, 15, 0},
	}
	toll_table := [][]int{
		{0, 300, 500, 600, 700, 1350, 1650},
		{300, 0, 350, 450, 600, 1150, 1500},
		{500, 350, 0, 250, 400, 1000, 1350},
		{600, 450, 250, 0, 250, 850, 1300},
		{700, 600, 400, 250, 0, 600, 1150},
		{1350, 1150, 1000, 850, 600, 0, 500},
		{1650, 1500, 1350, 1300, 1150, 500, 0},
	}
	for scanner.Scan() {
		d, _ := strconv.Atoi(scanner.Text())
		if d == 0 {
			break
		}
		d--
		scanner.Scan()
		dbuf := strings.Split(scanner.Text(), " ")
		dh, _ := strconv.Atoi(dbuf[0])
		dm, _ := strconv.Atoi(dbuf[1])
		dtime := 100*dh+dm
		scanner.Scan()
		a, _ := strconv.Atoi(scanner.Text())
		a--
		scanner.Scan()
		abuf := strings.Split(scanner.Text(), " ")
		ah, _ := strconv.Atoi(abuf[0])
		am, _ := strconv.Atoi(abuf[1])
		atime := 100*ah+am
		toll := toll_table[d][a]
		if distance_table[d][a] <= 40 &&
			1730 <= dtime && dtime <= 1930 ||
			1730 <= atime && atime <= 1930 {
				toll = ((toll/2-1)/50+1)*50
		}
		fmt.Println(toll)
	}
}

C++: #include<iostream>
using namespace std;

int cost[8][8] = 
{
{0},
{0,0,300,500,600,700,1350,1650},
{0,6,0,350,450,600,1150,1500},
{0,13,7,0,250,450,1000,1350},
{0,18,12,5,0,250,850,1300},
{0,23,17,10,5,0,600,1150},
{0,43,37,30,25,20,0,500},
{0,58,52,45,40,35,15,0}
};

int l,lh,lm,a,ah,am;

int max(){
	if(l<a)
		return l;
	else
		return a;
}

int min(){
	if(l>a)
		return l;
	else
		return a;
}

int main(){
	while(true){
		cin >> l;
		if(!l)
			return 0;
		cin >> lh >> lm;
		lm+=lh*100;
		cin >> a;
		cin >> ah >> am;
		am+=ah*100;
		if(cost[min()][max()] > 40)
			cout << cost[max()][min()] << endl;
		else if(!((lm>=1730&&lm<=1930)||(am>=1730&&am<=1930)))
			cout << cost[max()][min()] << endl;
		else{
			bool flag = false;
			if((cost[max()][min()]/2)%50 > 0)
				flag = true;
			int ans = cost[max()][min()]/2-(cost[max()][min()]/2)%50;
			if(flag)
				ans+=50;
			cout << ans << endl;
		}
	}
}

C++: #include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

int main(void){
	int t[8][8];
	int l[8][8];

	t[1][2] = 300; t[1][3] = 500; t[1][4] = 600; t[1][5] = 700; t[1][6] = 1350; t[1][7] = 1650;
	t[2][3] = 350; t[2][4] = 450; t[2][5] = 600; t[2][6] = 1150; t[2][7] = 1500;
	t[3][4] = 250; t[3][5] = 400; t[3][6] = 1000; t[3][7] = 1350;
	t[4][5] = 250; t[4][6] = 850; t[4][7] = 1300;
	t[5][6] = 600; t[5][7] = 1150;
	t[6][7] = 500;

	l[1][2] = 6; l[1][3] = 13; l[1][4] = 18; l[1][5] = 23; l[1][6] = 43; l[1][7] = 58;
	l[2][3] = 7; l[2][4] = 12; l[2][5] = 17; l[2][6] = 37; l[2][7] = 52;
	l[3][4] = 5; l[3][5] = 10; l[3][6] = 30; l[3][7] = 45;
	l[4][5] = 5; l[4][6] = 25; l[4][7] = 40;
	l[5][6] = 20; l[5][7] = 35;
	l[6][7] = 15;

	int in,out,in_t,out_t,t1,t2;

	while(cin >> in && in){
		cin >> t1 >> t2;
		in_t = t1*100+t2;
		cin >> out;
		cin >> t1 >> t2;
		out_t = t1*100+t2;
		if(in > out){
			swap(in,out);
		}
		if(l[in][out] <= 40 && ((1730 <= in_t && in_t <= 1930) || (1730 <= out_t && out_t <= 1930))){
			int tmp = std::ceil((double)(t[in][out] / 2) / 50);
			cout << tmp * 50 << endl;
		}else{
			cout << t[in][out] << endl;
		}
	}
}

C++: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
typedef pair<int,int> P;
bool hangaku(int h,int m){
	if(h == 18){
		return true;
	}else if(h == 17){
		return m >= 30;
	}else if(h == 19){
		return m <= 30;
	}else{
		return false;
	}
}

int main(){
	int s,g;
	int kyori[8] = {0,0,6,13,18,23,43,58};
	map<P,int> price;
	price[P(1,2)] = 300;
	price[P(1,3)] = 500;
	price[P(1,4)] = 600;
	price[P(1,5)] = 700;
	price[P(1,6)] = 1350;
	price[P(1,7)] = 1650;
	price[P(2,3)] = 350;
	price[P(2,4)] = 450;
	price[P(2,5)] = 600;
	price[P(2,6)] = 1150;
	price[P(2,7)] = 1500;
	price[P(3,4)] = 250;
	price[P(3,5)] = 400;
	price[P(3,6)] = 1000;
	price[P(3,7)] = 1350;
	price[P(4,5)] = 250;
	price[P(4,6)] = 850;
	price[P(4,7)] = 1300;
	price[P(5,6)] = 600;
	price[P(5,7)] = 1150;
	price[P(6,7)] = 500;
	while(cin>>s,s){
		int h1,m1,h2,m2;
		cin>>h1>>m1>>g>>h2>>m2;
		if(s > g) swap(s,g);
		int ans = price[P(s,g)];
		if(hangaku(h1,m1) || hangaku(h2,m2)){
			if(kyori[g]-kyori[s] <= 40){
				if(ans % 100){
					ans = (ans+50)/2;
				}else{
					ans /= 2;
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
int a,b,c,d,e,f;

int u=17*60+30,v=19*60+30;

int t[8][8]={
  {0,0,0,0,0,0,0,0},
  {0, 0, 300, 500, 600, 700,1350,1650},
  {0, 6,   0, 350, 450, 600,1150,1500},
  {0,13,   7,   0, 250, 400,1000,1350},
  {0,18,  12,   5,   0, 250, 850,1300},
  {0,23,  17,  10,   5,   0, 600,1150},
  {0,43,  37,  30,  25,  20,   0, 500},
  {0,58,  52,  45,  40,  35,  15,   0}
};

bool check(){
  if(t[max(a,d)][min(a,d)]>40)return false;
  
  int x=b*60+c,y=e*60+f;

  if((x<u||v<x)&&(y<u||v<y)){
    return false;
  }

  return true;
}
int change(int x){
  if(x%100==50){
    x-=50;
    return x/2+50;
  }else{
    return x/2;
  }
}

int main(){
  while(cin>>a&&a){
    cin>>b>>c>>d>>e>>f;
    if(check()){

      cout<<change(t[min(a,d)][max(a,d)])<<endl;
    }else{
      cout<<t[min(a,d)][max(a,d)]<<endl;
    }
  }
  return 0;
}