Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:共享一下本人AC的代码In Reply To:共享一下本人AC的代码 Posted by:walker01 at 2010-04-05 11:27:03 > 这道题易出错的细节很多, 一定要先将题意吃透,理清思路,合理规划采用的数据结构。这种模拟题适合用面向对象的思想。第一次因为忘记更新头结点而WA,第二次就AC了。与大家分享一下本人AC的代码(176k, 0ms),希望能对大家有所帮助。 > > Source Code > #include <iostream> > using namespace std; > > enum Status > { > UNCERTAIN = 0, > INSINGLE, > INBOTH > }; > > enum JoinType > { > NONE = 0, > FIRST, > SECOND, > BOTH > }; > > struct TeamRecord > { > int rank1; > int rank2; > int sumRanks; > JoinType joinType; > }; > > struct LinkTeamRecord > { > int teamId; > LinkTeamRecord *right; > LinkTeamRecord *next; > LinkTeamRecord(int _teamId): right(NULL),next(NULL) > { > teamId = _teamId; > } > ~LinkTeamRecord() > { > if(right) delete right; > if(next) delete next; > } > }; > > //globals/// > const int TEAMSCOUNT = 100; > const char *DELIMITERS = " \n"; > char LINEDATA[3*TEAMSCOUNT]; > TeamRecord g_teamRecords[TEAMSCOUNT+1]; > int g_contestRanks[4*TEAMSCOUNT+2]; > //////////// > > class ContestInfoReader > { > public: > ContestInfoReader() > { > memset(g_teamRecords, 0, sizeof(g_teamRecords)); > memset(g_contestRanks, 0, sizeof(g_contestRanks)); > } > void InitData() > { > m_currentRankIndex = 0; > m_currentContestNumber = 1; > ReadContestData(); > > gets(LINEDATA); > > FillContestRank(0); > m_currentContestNumber = 2; > ReadContestData(); > FillContestRank(0); > } > bool NextTeamOfBothType() > { > ++m_currentTeamId; > for(int i=m_currentTeamId; i<=TEAMSCOUNT; ++i) > if(g_teamRecords[i].joinType == BOTH) > { > m_currentTeamId = i; > return true; > }; > return false; > } > bool NextTeamOfSingleType() > { > int teamIndex = g_contestRanks[++m_currentRankIndex]; > while(teamIndex != 0) > { > JoinType type = (m_currentContestNumber==1)?FIRST:SECOND; > if(g_teamRecords[teamIndex].joinType != type) > teamIndex = g_contestRanks[++m_currentRankIndex]; > else > { > m_currentTeamId = teamIndex; > return true; > } > } > > if(PrepareForNextGroup()) > return NextTeamOfSingleType(); > else > return false; > } > void ResetCurrentTeamId() > { > m_currentTeamId = 0; > } > void ResetCurrentRank() > { > m_currentRankIndex = -1; > m_currentContestNumber = 1; > PrepareForNextGroup(); > } > > int CurrentTeamId() > { > return m_currentTeamId; > } > Status& CurrentStatus() > { > return m_status; > } > int CurrentGroupId() > { > return m_groupIndex; > } > protected: > void ReadContestData() > { > int rankSum, rankCur; > int teamId, teamCount; > char *pCur; > > gets(LINEDATA); > sscanf(LINEDATA, "%d", &teamCount); > > rankSum = 0; > for(int i=0; i<teamCount; ++i) > { > gets(LINEDATA); > rankCur = rankSum+1; > pCur = strtok(LINEDATA, DELIMITERS); > while(pCur) > { > ++rankSum; > teamId = atoi(pCur); > FillTeamRecord(teamId, rankCur); > FillContestRank(teamId); > pCur = strtok(NULL, DELIMITERS); > } > FillContestRank(0); > } > } > void FillTeamRecord(int teamId, int rank) > { > if(m_currentContestNumber == 1) > { > g_teamRecords[teamId].joinType = FIRST; > g_teamRecords[teamId].rank1 = rank; > } > else if(m_currentContestNumber == 2) > { > if(g_teamRecords[teamId].joinType == NONE) > { > g_teamRecords[teamId].joinType = SECOND; > g_teamRecords[teamId].rank2 = rank; > } > else if(g_teamRecords[teamId].joinType == FIRST) > { > int rank1 = g_teamRecords[teamId].rank1; > g_teamRecords[teamId].joinType = BOTH; > g_teamRecords[teamId].rank2 = rank; > g_teamRecords[teamId].sumRanks = rank1+rank; > } > } > } > void FillContestRank(int teamId) > { > g_contestRanks[m_currentRankIndex++] = teamId; > } > bool PrepareForNextGroup() > { > int rankIndex = m_currentRankIndex+1; > if(g_contestRanks[rankIndex] > 0) > { > SetGroupStatus(); > if(m_status == UNCERTAIN) > { > JumpCurrentGroup(); > return PrepareForNextGroup(); > } > return true; > } > else if(m_currentContestNumber == 1) > { > ++m_currentRankIndex; > m_currentContestNumber = 2; > return PrepareForNextGroup(); > } > return false; > } > void SetGroupStatus() > { > m_groupIndex = 0; > bool bUncertain = false; > for(int i=m_currentRankIndex+1; ;++i) > { > int teamIndex = g_contestRanks[i]; > if(teamIndex == 0) > break; > > if(g_teamRecords[teamIndex].joinType == BOTH) > { > if(m_groupIndex == 0) > m_groupIndex = teamIndex; > else if(g_teamRecords[m_groupIndex].sumRanks != g_teamRecords[teamIndex].sumRanks) > { > bUncertain = true; > break; > } > } > } > > if(bUncertain) > m_status = UNCERTAIN; > else if(m_groupIndex == 0) > m_status = INSINGLE; > else > m_status = INBOTH; > } > void JumpCurrentGroup() > { > int teamIndex = g_contestRanks[++m_currentRankIndex]; > while(teamIndex != 0) > teamIndex = g_contestRanks[++m_currentRankIndex]; > } > private: > //for iteration > int m_currentTeamId; > int m_currentRankIndex; > int m_currentContestNumber; > > //group status > Status m_status; > int m_groupIndex; > }; > > class ContestRatingSorter > { > public: > ContestRatingSorter() : m_pHead(NULL) > {} > ~ContestRatingSorter() > { > if(m_pHead) > delete m_pHead; > } > > bool PrepareForInsert(int id) > { > m_pInsert = new LinkTeamRecord(id); > if(m_pHead) > { > ResetFromHead(); > return true; > } > m_pHead = m_pInsert; > return false; > } > void InsertBothType() > { > int sumInsert = g_teamRecords[m_pInsert->teamId].sumRanks; > int sumCurrent = g_teamRecords[m_pHead->teamId].sumRanks; > > if(sumInsert > sumCurrent) > { > while(NextGroup()) > { > sumCurrent = g_teamRecords[m_pCurrentGroup->teamId].sumRanks; > if(sumInsert <= sumCurrent) > break; > } > } > > if(sumInsert == sumCurrent) > InsertInGroup(); > else > NewGroup(); > } > void InsertSingleInBothType(int groupId) > { > Find(groupId); > InsertInGroup(); > } > bool InsertSingleType() > { > bool bUncertain = false; > bool bFindGroup = false; > LinkTeamRecord *pFront = NULL; > LinkTeamRecord *pBack = NULL; > > JoinType typeInsert = g_teamRecords[m_pInsert->teamId].joinType; > int rankInsert = GetSingleRank(typeInsert, m_pInsert->teamId); > > do > { > int rankCurrent = GetSingleRank(typeInsert, m_pCurrentNode->teamId); > if(rankCurrent != 0) > { > if(rankInsert > rankCurrent) > { > if(pBack) > { > bUncertain = true; > break; > } > pFront = m_pCurrentGroup; > } > else if(rankInsert < rankCurrent) > { > if(m_pCurrentGroup == pFront) > { > bUncertain = true; > break; > } > if(!pBack) > pBack = m_pCurrentGroup; > } > else > { > bFindGroup = true; > break; > } > } > } > while(Next()); > > if(!bUncertain) > { > if(bFindGroup) > InsertInGroup(); > else > InsertBetweenGroups(pFront, pBack); > return true; > } > > if(m_pInsert) > delete m_pInsert; //free memory > return false; > } > void PrintRatingList() > { > LinkTeamRecord *pGroup = m_pHead; > LinkTeamRecord *pNode = m_pHead; > while(pGroup) > { > printf("%d", pGroup->teamId); > pNode = pGroup->right; > while(pNode) > { > printf("%s%d"," ",pNode->teamId); > pNode = pNode->right; > } > printf("\n"); > pGroup = pGroup->next; > } > } > protected: > void ResetFromHead() > { > ResetFromGroup(NULL); > } > void ResetFromGroup(LinkTeamRecord *pPre) > { > LinkTeamRecord *pCur = NULL; > if(!pPre) > pCur = m_pHead; > else > pCur = pPre->next; > > m_pPreviousNode = NULL; > m_pCurrentNode = pCur; > m_pPreviousGroup = pPre; > m_pCurrentGroup = pCur; > } > bool Next() > { > if(!NextNodeInGroup()) > return NextGroup(); > return true; > } > bool NextGroup() > { > m_pPreviousGroup = m_pCurrentGroup; > m_pCurrentGroup = m_pCurrentGroup->next; > m_pPreviousNode = NULL; > m_pCurrentNode = m_pCurrentGroup; > return m_pCurrentGroup!=NULL; > } > bool NextNodeInGroup() > { > m_pPreviousNode = m_pCurrentNode; > m_pCurrentNode = m_pCurrentNode->right; > return m_pCurrentNode!=NULL; > } > void InsertInGroup() > { > //restart from current group > m_pPreviousNode = NULL; > m_pCurrentNode = m_pCurrentGroup; > > int idInsert = m_pInsert->teamId; > if(idInsert > m_pCurrentGroup->teamId) > { > while(NextNodeInGroup()) > { > if(idInsert < m_pCurrentNode->teamId) > break; > } > } > NewNode(); > } > void InsertBetweenGroups(LinkTeamRecord *front, LinkTeamRecord *back) > { > ResetFromGroup(front); > > int rankCurrent = 0; > int rankInsert = GetSingleRank(m_pInsert->teamId); > > while(m_pCurrentGroup != back) > { > rankCurrent = GetSingleRank(m_pCurrentGroup->teamId); > if(rankInsert <= rankCurrent) > break; > NextGroup(); > } > > if(rankInsert == rankCurrent) > InsertInGroup(); > else > NewGroup(); > } > void NewGroup() > { > if(m_pCurrentGroup == m_pHead) > { > //new head > m_pInsert->next = m_pHead; > m_pHead = m_pInsert; > } > else > { > //new group > m_pPreviousGroup->next = m_pInsert; > m_pInsert->next = m_pCurrentGroup; > } > } > void NewNode() > { > if(m_pCurrentNode == m_pCurrentGroup) > { > if(m_pPreviousGroup) > m_pPreviousGroup->next = m_pInsert; > > m_pInsert->right = m_pCurrentGroup; > m_pInsert->next = m_pCurrentGroup->next; > m_pCurrentGroup->next = NULL; > > //new head > if(!m_pPreviousGroup) > m_pHead = m_pInsert; > } > else > { > m_pPreviousNode->right = m_pInsert; > m_pInsert->right = m_pCurrentNode; > } > } > LinkTeamRecord *Find(int id) > { > if(id != m_pHead->teamId) > while(Next()) > { > if(id == m_pCurrentNode->teamId) > break; > }; > return m_pCurrentNode; > } > int GetSingleRank(int teamId) > { > int rank = 0; > TeamRecord team = g_teamRecords[teamId]; > if(team.joinType == FIRST) > rank = team.rank1; > else if(team.joinType == SECOND) > rank = team.rank2; > return rank; > } > int GetSingleRank(JoinType type, int teamId) > { > int rank = 0; > TeamRecord team = g_teamRecords[teamId]; > if(type == FIRST) > rank = team.rank1; > else if(type == SECOND) > rank = team.rank2; > return rank; > } > private: > LinkTeamRecord *m_pHead; > LinkTeamRecord *m_pInsert; > > //for iteration > LinkTeamRecord *m_pPreviousGroup; > LinkTeamRecord *m_pCurrentGroup; > LinkTeamRecord *m_pPreviousNode; > LinkTeamRecord *m_pCurrentNode; > }; > int main() > { > ContestInfoReader reader; > ContestRatingSorter sorter; > > reader.InitData(); > reader.ResetCurrentTeamId(); > while(reader.NextTeamOfBothType()) > { > int id = reader.CurrentTeamId(); > if(sorter.PrepareForInsert(id)) > sorter.InsertBothType(); > } > > reader.ResetCurrentRank(); > while(reader.NextTeamOfSingleType()) > { > int id = reader.CurrentTeamId(); > if(sorter.PrepareForInsert(id)) > { > Status status = reader.CurrentStatus(); > if(status == INBOTH) > { > int groupId = reader.CurrentGroupId(); > sorter.InsertSingleInBothType(groupId); > } > else if(status == INSINGLE) > sorter.InsertSingleType(); > } > } > > sorter.PrintRatingList(); > return 0; > } 请问,例子的输出中为什么21不在4和20的后面啊?rule B的后半段是什么意思啊? Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator