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;
}


发布了67 篇原创文章 · 获赞 0 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览