UVA - 540 - Team Queue

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=103&page=show_problem&problem=481


題意:

    輸入幾個隊伍,各隊列有其隊員。接着輸入進隊出隊指令,模擬隊列,輸出每次出隊的隊員號。

    其中,該隊列有以下特點:進隊前,隊列如a.1 - b.1 - c.1 - d.1;b.2進隊時,接在自己隊員後面,隊列變成a.1 - b.1 - b.2 - c.1 - d.1,同理,其它隊隊員進隊列也是一樣的道理;出隊時,如普通隊列一樣,隊首出隊。


解題:

    研究了好久的題目啊。看了別人題解才搞定的。

    一開始想用queue+vector來模擬解決,可發現queue/vector不能嵌套使用。

    學習了網上的解決方法,自己用數組來模擬各隊進隊列的情況。


注意:

    a. 在可能存在空行或回車的情況下,使用gets(char*)來消除更保證,用cin.ignore只能消一個字符,如果是多空格空行就解決不了了。

    b. 雖然使用istringstream分離字符串、用int member = atoi(word.c_str())很方便;如果數據行結構已經很明確,一次使用sscanf(char*,  "%s %d", str, &num)會更高效準確。


#include <iostream>
#include <list>
#include <map>
#include <string.h>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

#define LOCAL_TEST

const int NUMBER_TEAMS = 1000;

struct ltstr
{
	bool operator()(const int a, const int b)const
	{
		return a < b;
	}
};

map <int,int, ltstr> mapTeammates;
int szTeammates[NUMBER_TEAMS][2000];
int szIndexQueueFront[NUMBER_TEAMS];
int szIndexQueueBack[NUMBER_TEAMS];

int TeamsQueue[NUMBER_TEAMS];
int TeamsFront;
int TeamsBack;

// use to count whether the team is visited
int TeamsVis[NUMBER_TEAMS];


void Init()
{
	mapTeammates.clear();
	memset(szTeammates, 0, NUMBER_TEAMS * 2000);
	memset(szIndexQueueFront, 0, NUMBER_TEAMS);
	memset(szIndexQueueBack, -1, NUMBER_TEAMS);
	memset(TeamsQueue, 0, NUMBER_TEAMS);
	TeamsFront = 0;
	TeamsBack = -1;
	memset(TeamsVis, 0, NUMBER_TEAMS);
}


void Enqueue(int member)
{
	// Get the member's TeamNumber
	int iTeamnumber = mapTeammates[member];

	//  if the team hasn't been visited
	if ( TeamsVis[iTeamnumber] == 0 )
	{
		TeamsVis[iTeamnumber] = 1;
		TeamsQueue[++TeamsBack] = iTeamnumber;
	} // end if

	// Corresponding BackNumber plus 1, and set member into the team
	szTeammates[iTeamnumber][++szIndexQueueBack[iTeamnumber]] = member;
}


void Dequeue()
{
	// if TeamQueue is not empty
	if ( TeamsFront <= TeamsBack )
	{
		int iTeamnumber = TeamsQueue[TeamsFront];
		int iFront = szIndexQueueFront[iTeamnumber];
		int iBack = szIndexQueueBack[iTeamnumber];
		// In "Teams of iTeamnumber", if front <= back, in other words, list is no empty
		if ( szIndexQueueFront[iTeamnumber] <= szIndexQueueBack[iTeamnumber] )
		{
			cout <<szTeammates[iTeamnumber][szIndexQueueFront[iTeamnumber]];
			cout <<'\n';
			szIndexQueueFront[iTeamnumber]++;
			// if list becomes empty
			if ( szIndexQueueFront[iTeamnumber] > szIndexQueueBack[iTeamnumber] )
			{
				// Remove this iTeamnumber
				TeamsFront++;
				TeamsVis[iTeamnumber] = 0;
			} // end if
		} // end if
	} // end if

}


void PrintOut()
{
	if ( TeamsFront <= TeamsBack )
		for ( int i=TeamsFront; i<=TeamsBack; i++ )
			for ( int k=szIndexQueueFront[i]; k<=szIndexQueueBack[i]; k++ )
			{
				cout <<szTeammates[i][k];
				cout <<'\n';
			} // end for
}


int main()
{
#ifdef LOCAL_TEST
	freopen("f:\\in.txt", "r", stdin);
	freopen("f:\\out.txt", "w+", stdout);
#endif
	int nCase = 0;
	while ( 1 )
	{
		// Get the number of teams
		int numberOfTeams;
		cin >>numberOfTeams;
		if ( numberOfTeams == 0 )
			break;

		// Initialize map and arrays
		Init();
		nCase++;

		// Get the teammates
		for ( int i=0; i<numberOfTeams; i++ )
		{
			int numberOfTeammates;
			int member;
			cin >>numberOfTeammates;
			for ( int k=0; k<numberOfTeammates; k++ )
			{
				cin >>member;
				mapTeammates.insert(make_pair(member, i));
			} // end for
		} // end for

		cout <<"Scenario #" <<nCase <<'\n';
		// Get inputCode and process
		char temp[50];
		// erase blank line(which may contain several blank spaces)
		gets(temp);
		while ( gets(temp) )
		{
			string strWords(temp);
			string word;
			istringstream strStream(strWords);
			strStream >>word;
			if ( word == "STOP" )
			{
				cout <<"\n";
				break;
			} // end if
			else
				if ( word == "DEQUEUE" )
					Dequeue();
				else
				{
					// OK version - 1
// 					int num;  
// 					char cmd[20];  
// 					sscanf(temp, "%s %d", cmd, &num);
// 					Enqueue(num);
 					// OK version - 2
					strStream >>word;
					int member = atoi(word.c_str());
					Enqueue(member);
				}
		} // end while

	} // end while
	
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章