UVA - 540 - Team Queue

来源:互联网 发布:丹江口水电站待遇 知乎 编辑:程序博客网 时间:2024/05/22 08:07

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_TESTconst 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 visitedint 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 TeamNumberint iTeamnumber = mapTeammates[member];//  if the team hasn't been visitedif ( TeamsVis[iTeamnumber] == 0 ){TeamsVis[iTeamnumber] = 1;TeamsQueue[++TeamsBack] = iTeamnumber;} // end if// Corresponding BackNumber plus 1, and set member into the teamszTeammates[iTeamnumber][++szIndexQueueBack[iTeamnumber]] = member;}void Dequeue(){// if TeamQueue is not emptyif ( 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 emptyif ( szIndexQueueFront[iTeamnumber] <= szIndexQueueBack[iTeamnumber] ){cout <<szTeammates[iTeamnumber][szIndexQueueFront[iTeamnumber]];cout <<'\n';szIndexQueueFront[iTeamnumber]++;// if list becomes emptyif ( szIndexQueueFront[iTeamnumber] > szIndexQueueBack[iTeamnumber] ){// Remove this iTeamnumberTeamsFront++;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_TESTfreopen("f:\\in.txt", "r", stdin);freopen("f:\\out.txt", "w+", stdout);#endifint nCase = 0;while ( 1 ){// Get the number of teamsint numberOfTeams;cin >>numberOfTeams;if ( numberOfTeams == 0 )break;// Initialize map and arraysInit();nCase++;// Get the teammatesfor ( 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 forcout <<"Scenario #" <<nCase <<'\n';// Get inputCode and processchar 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 ifelseif ( word == "DEQUEUE" )Dequeue();else{// OK version - 1// int num;  // char cmd[20];  // sscanf(temp, "%s %d", cmd, &num);// Enqueue(num); // OK version - 2strStream >>word;int member = atoi(word.c_str());Enqueue(member);}} // end while} // end whilereturn 0;}


0 0
原创粉丝点击