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 |
共享一下本人AC的代码这道题易出错的细节很多, 一定要先将题意吃透,理清思路,合理规划采用的数据结构。这种模拟题适合用面向对象的思想。第一次因为忘记更新头结点而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; } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator