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 <bits/stdc++.h>
using namespace std;

int tb[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}
};


int d,hd,md,a,ha,ma;

int to_m(int h,int m){
	return h * 60 + m;
}
bool time_ok(){
	int dt = to_m(hd,md);
	int at = to_m(ha,ma);
	int t1730 = to_m(17,30);
	int t1930 = to_m(19,30);
	return (dt >= t1730 && dt <= t1930) || (at >= t1730 && at <= t1930);
}
bool is_half(){
	return tb[a][d] <= 40 && time_ok();
}
int roundup(int f){
	int h = f % 50;
	if(h > 0){
		return f - h + 50;
	}
	else{
		return f;
	}
}
int fee(){
	return is_half() ? roundup(tb[d][a] / 2) : roundup(tb[d][a]);
}

int main(){
	while(cin >> d, d != 0){
		cin >> hd >> md >> a >> ha >> ma;
		cout << fee() << endl;
	}
	return 0;
}

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

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

int cost[8][8]={
{   0,   0,   0,   0,   0,   0,   0,   0},
{   0,   0, 300, 500, 600, 700,1350,1650},
{   0, 300,   0, 350, 450, 600,1150,1500},
{   0, 500, 350,   0, 250, 400,1000,1350},
{   0, 600, 450, 250,   0, 250, 850,1300},
{   0, 700, 600, 400, 250,   0, 600,1150},
{   0,1350,1150,1000, 850, 600,   0, 500},
{   0,1650,1500,1350,1300,1150, 500,   0}
};

int dis[8][8]={
{ 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 6,13,18,23,43,58},
{ 0, 6, 0, 7,12,17,37,52},
{ 0,13, 7, 0, 5,10,30,45},
{ 0,18,12, 5, 0, 5,25,40},
{ 0,23,17,10, 5, 0,20,35},
{ 0,43,37,30,25,20, 0,15},
{ 0,58,52,45,40,35,15, 0}
};

int main() {
	int n1,n2,h1,h2,m1,m2;
	while(n1=in()){
		cin>>h1>>m1>>n2>>h2>>m2;
		int c=cost[n1][n2];
		int d=dis[n1][n2];
		int time1=h1*60+m1;
		int time2=h2*60+m2;
		if(d<=40&&(17*60+30<=time1&&time1<=19*60+30||17*60+30<=time2&&time2<=19*60+30)){
			c/=2;
			if(c%50){
				c+=50-c%50;
			}
		}
		cout<<c<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <stdio.h>
using namespace std;
int main() {
 char c1[2],c2[2];
 int h,m,ic[2],f[2],i,k,a,b;
 int g[6][7]={{0,300,500,600,700,1350,1650}, {0,0,350,450,600,1150,1500}, {0,0,0,250,400,1000,1350},
              {0,0,0,0,250,850,1300}, {0,0,0,0,0,600,1150}, {0,0,0,0,0,0,500}};
 while(true) {
	 for (i=0;i<2;i++) {
		 cin >> ic[i];
		 if (ic[i]==0) return 0;
		 ic[i]--;
		 cin >> c1 >> c2;
		 h=(c1[0]-'0')*10+(c1[1]-'0');
		 m=(c2[0]-'0')*10+(c2[1]-'0');
		 if (h==17 && m==30) f[i]=1; else if (h==19 && m==30) f[i]=3; else
			 if ((h==17 && m>30) || h==18 || (h==19 && m<30)) f[i]=2; else f[i]=0; 
		 }
	 if (ic[0]>ic[1]) { a=ic[0]; ic[0]=ic[1]; ic[1]=a; }
	 k=g[ic[0]][ic[1]]; a=f[0]; b=f[1];
	 if(k<1350) 
		 if((a==0 && b==1)||(a==1 && b==2)||(a==0 && b==2)||(a==2 && b==3)||(a==2 && b==0)||(a==3 && b==0)) k=k % 100>0 ? k/2+25:k/2;
	 cout << k << endl;
 }
return 0;
 }

C++: //07
#include<iostream>
#include<algorithm>

#define T(h,m) ((h)*60+(m))

using namespace std;

int main(){
  for(int s;cin>>s,s;){
    int sh,sm;
    int t,th,tm;
    cin>>sh>>sm>>t>>th>>tm;
    s--;
    t--;
    int f[7][7]={{0,300,500,600,700,1350,1650},{0,0,350,450,600,1150,1500},{0,0,0,250,400,1000,1350},{0,0,0,0,250,850,1300},{0,0,0,0,0,600,1150},{0,0,0,0,0,0,500},{0,0,0,0,0,0,0}};
    int d[7][7]={{0,0,0,0,0,0,0},{6,0,0,0,0,0,0},{13,7,0,0,0,0,0},{18,12,5,0,0,0,0},{23,17,10,5,0,0,0},{43,37,30,25,20,0,0},{58,52,45,40,35,15}};
    int sum=max(f[s][t],f[t][s]);
    if(!((T(sh,sm)<T(17,30)&&T(19,30)<T(th,tm))||T(sh,sm)>T(19,30)||T(th,tm)<T(17,30))&&max(d[s][t],d[s][t])<40){
      sum=sum/2+((sum%100==50)?25:0);
    }
    cout<<sum<<endl;
  }
  return 0;
}

C++: // AOJ 0163
#include <iostream>

using namespace std;

int main(void)
{
	int data[7][7] = {{0, 300, 500, 600, 700, 1350, 1650},
					  {6, 0, 350, 450, 600, 1150, 1500},
					  {13, 7, 0, 250, 400, 1000, 1350},
					  {18, 12, 5, 0, 250, 850, 1300},
					  {23, 17, 10, 5, 0, 600, 1150},
					  {43, 37, 30, 25, 20, 0, 500},
					  {58, 52, 45, 40, 35, 15}};
	int start, end, st[2], et[2];
	while (cin >> start, start){
		cin >> st[0] >> st[1];
		cin >> end >> et[0] >> et[1];
		start--; end--;

		bool f = false;
		if (17 <= st[0] && st[0] <= 19){
			if (st[0] == 18) f = true;
			else if ((st[0] == 17 && 30 <= st[1]) || (st[0] == 19 && 30 >= st[1])){
				f = true;
			}
		}
		if (17 <= et[0] && et[0] <= 19){
			if (et[0] == 18) f = true;
			else if ((et[0] == 17 && 30 <= et[1]) || (et[0] == 19 && 30 >= et[1])){
				f = true;
			}
		}

		if (start < end) swap(start, end);
		int k = data[start][end];
		int ret = data[end][start];
		if (40 < k) f = false;

		ret /= 50.0;
		if (f){
			if (ret % 2) ret++;
			ret /= 2;
		}
		cout << (int)(ret * 50) << endl;
	}

	return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;
 
const int price[7][7] = {
    {-1, 300, 500, 600, 700, 1350, 1650},
    {-1, -1, 350, 450, 600, 1150, 1500},
    {-1, -1, -1, 250, 400, 1000, 1350},
    {-1, -1, -1, -1, 250, 850, 1300},
    {-1, -1, -1, -1, -1, 600, 1150},
    {-1, -1, -1, -1, -1, -1, 500}
};
 
const int dist[7][7] = {
    {-1, 6, 13, 18, 23, 43, 58},
    {-1, -1, 7, 12, 17, 37, 52},
    {-1, -1, -1, 5, 10, 30, 45},
    {-1, -1, -1, -1, 5, 25, 40},
    {-1, -1, -1, -1, -1, 20, 35},
    {-1, -1, -1, -1, -1, -1, 15}
};
 
int _start = 17*60 + 30, _end = 19*60 + 30;
 
int main()
{
    int sIC, sh, sm, tIC, th, tm;
 
    while (scanf("%d", &sIC) ,sIC) {
	scanf("%d%d", &sh ,&sm);
	scanf("%d%d%d", &tIC ,&th ,&tm);
 
	sIC--; tIC--;
	bool ok1 = 0, ok2 = 0;
	int ssum = sh*60 + sm, tsum = th*60 + tm;
 
	if ((_start <= ssum && ssum <= _end) ||
	   (_start <= tsum && tsum <= _end)) ok1 = 1;
 
	if (dist[sIC][tIC] <= 40) ok2 = 1;
  
	int ans = price[sIC][tIC];
	if (ok1 && ok2) {
	    ans = (ans / 50 + 1) / 2;
	    ans *= 50;
	}
	printf("%d\n" ,ans);
    }
    return 0;
}