Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

type chair struct {
	group_id, rest_time int
}

type info struct {
	group_id, num, wait_sum, before_go int
	fixed                              bool
}

func main() {
	ans := make([]int, 100)
	chair := make([]chair, 17)
	for i := 0; i < 17; i++ {
		chair[i].group_id = -1
	}
	info := make([]info, 100)
	for i := 0; i <= 99; i++ {
		info[i].group_id = i
		info[i].before_go = 5 * i
		info[i].wait_sum = 0
		if i%5 == 1 {
			info[i].num = 5
		} else {
			info[i].num = 2
		}
		info[i].fixed = false
	}
	count := 0
	FLG := 0
	tmp_num := 0
	isOK := false
	waitFLG := false
	for {
		for i := 0; i < 17; i++ {
			if chair[i].group_id != -1 {
				chair[i].rest_time--
				if chair[i].rest_time <= 0 {
					chair[i].group_id = -1
				}
			}
		}
		waitFLG = false
		count = 0
		for i := 0; i < 100; i++ {
			if info[i].fixed {
				continue
			}
			if waitFLG == false && info[i].before_go == 0 {
				FLG = -1
				tmp_num = info[i].num
				for k := 0; k <= 17-tmp_num; k++ {
					isOK = true
					for p := 0; p < tmp_num; p++ {
						if chair[k+p].group_id != -1 {
							isOK = false
							break
						}
					}
					if isOK {
						FLG = k
						break
					}
				}
				if FLG != -1 {
					for k := FLG; k < FLG+tmp_num; k++ {
						chair[k].group_id = info[i].group_id
						chair[k].rest_time = 17*(i%2) + 3*(i%3) + 19
						info[i].fixed = true
					}
				} else {
					waitFLG = true
					info[i].wait_sum++
					count++
				}
			} else {
				if info[i].before_go == 0 {
					info[i].wait_sum++
				} else {
					info[i].before_go--
				}
				count++
			}
		}
		if count == 0 {
			break
		}
	}
	for i := 0; i <= 99; i++ {
		ans[i] = info[i].wait_sum
	}
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		fmt.Println(ans[n])
	}
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

typedef pair<int,int> P;
// (時刻,イベント,グループ番号)の組を表す.
// イベントは 離席 or 着席 を -1 or 1 で表す.
typedef pair< int , P > State;

// グループ番号 i の人数を返す.
int get_num(int i){
	return (i%5 == 1)? 5 : 2 ;
}

// グループ id が座れるかどうか返す. 座れる時はsekiの状態も変わる.
bool check(vector<int>& seki , int id ){
	int num = get_num(id);
	for(int i=0 ; i < 17 ; i++ ){
		if( num == 2 ){
			if( i+1 < 17 && seki[i] == -1 && seki[i+1] == -1 ){
				seki[i] = seki[i+1] = id;
				return true;
			}
		}else{
			if( i+4 < 17 && seki[i] == -1 && seki[i+1] == -1 && seki[i+2] == -1 && seki[i+3] == -1 && seki[i+4] == -1 ){
				seki[i] = seki[i+1] = seki[i+2] = seki[i+3] = seki[i+4] = id;
				return true;
			}
		}
	}
	return false;
}

// グループ id を離席させる. 離席するとsekiの状態も変わる.
void remove(vector<int>& seki , int id ){
	for(int i=0 ; i < 17 ; i++ ){
		if( seki[i] == id ) seki[i] = -1;
	}
}

int main(){
	// (時刻,イベント,グループ番号) の組を保持し, 時刻の早いほうから処理する.
	priority_queue< State , vector<State> , greater<State> > q;
	// (グループ番号,到着時刻) の組を保持し, 今並んでいる人々を表す.
	for(int i=0 ; i < 100 ; i++ ){
		q.push( State( 5*i , P(+1,i) ) );
	}
	// seki[i] := i番目の席に座っている人の番号, 座ってないときは -1
	vector<int> seki(17);
	for(int i=0 ; i < 17 ; i++ ) seki[i] = -1;
	
	// que := 待ち行列, (グループ番号を保持する)
	queue<int> que;
	
	// wait[i] := グループ i の待ち時間
	int wait[100] = {0}; 
	
	while( !q.empty() ){
		int t = q.top().first;
		int event = q.top().second.first;
		int id = q.top().second.second;
		q.pop();
		
		/*printf("%3d : ", t);
		for(int i=0 ; i < 17 ; i++ ){
			if( seki[i] == -1 ){
				printf("__");
			}else{
				printf("%2d", seki[i] );
			}
		}*/
		
		
		// グループ id が着席するとき 
		if( event == 1 ){
			
			// 行列があるとき
			if( !que.empty() ){
				que.push( id );
				
				//printf(": %d is wait! \n", id);
			}else if( check( seki , id ) ){// 座れるかチェック, 座れなかったら行列に並ぶ.
				int eat_time = 17 * (id%2) + 3 * (id%3) + 19;
				q.push( State( t + eat_time , P(-1,id) ) );
				
				//printf(": %d is sit! \n", id);
			}else{
				que.push( id );
				
				//printf(": %d is wait! \n", id);
			}
		}else{ // グループ id が離席するとき
			remove( seki , id );
			//printf(": %d is leave! ", id);
			// 行列の先頭の人が座れるかチェック
			bool flag = false;
			do{
				if( que.empty() ) break;
				flag = false;
				int id_2 = que.front();
				if( check( seki , id_2 ) ){
					flag = true;
					int eat_time = 17 * (id_2%2) + 3 * (id_2%3) + 19;
					q.push( State( t + eat_time , P(-1,id_2) ) );
					wait[id_2] = t - id_2 * 5;
					que.pop();
					//printf("&& %d is sit! ", id_2);
				}
			}while( flag );
			//puts("");
		}
	}
	int n;
	while( cin >> n ){
		cout << wait[n] << endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;

int search_sequence(vector<int> &a,int n){
	int cnt=0;
	for(int i=0;i<a.size();++i){
		if(a[i]==-1)++cnt;
		else cnt=0;
		if(cnt>=n)return i-cnt+1;
	}
	return -1;
}

int main(void){
    vector<int> seat(17,-1);
    int time[100],finish[100];
    queue<pair<int,int> > q;
    int x=0,y=0;
    for(int t=0;y<100;++t){
      if(t%5==0) q.push(make_pair(x++,(x%5==1)?5:2));
      for(int i=0;i<17;++i){
        if(seat[i]!=-1&&finish[seat[i]]==t){
        	fill(&seat[i],&seat[i+((seat[i]%5==1)?5:2)],-1);
        	//cerr<<t<<":";for(int i=0;i<17;++i)cerr<<seat[i]<<((i!=16)?" ":"\n");
      	}
      }
      while(search_sequence(seat,q.front().second)!=-1){
        fill(&seat[search_sequence(seat,q.front().second)],&seat[search_sequence(seat,q.front().second)+q.front().second],q.front().first);
        //cerr<<t<<":";for(int i=0;i<17;++i)cerr<<seat[i]<<((i!=16)?" ":"\n");
        finish[q.front().first]=t+17*(q.front(
        ).first%2)+3*(q.front().first%3)+19;
        time[q.front().first]=t-5*q.front().first;
        q.pop();++y;
      }
    }
  int n;
  while(cin>>n){
  	cout<<time[n]<<endl;
  }
  return 0;
}