題目意思是說,給出一個數n,表示存在一個整數序列1……n,而後進行四種操做:ios
操做一:輸入x,y,表示將x移到y的左邊(若x原本就在y的左邊則忽略);數組
操做二:輸入x,y,表示將x移到y的右邊(若x原本就在y的右邊則忽略);this
操做三:輸入x,y,表示交換x和y。code
操做四:將整個序列倒置。ci
最後要求的是操做後的整個序列奇數項的和。io
數據爲100000,直接模擬確定超時,用STL的鏈表也會超,個人想法是用數組模擬鏈表,left[i]和right[i]數組分別存放i的左值和右值。在整個過程當中,逆序操做最耗時間,因爲題目只須要求奇數項的和,在進行逆序操做時,咱們不必真真進行操做,只須要記錄逆序的次數便可,如果奇數次,則最後求整個序列的偶數項之和,偶數次就是求奇數項之和。還有一點就是,操做四的進行與否會對前兩種操做有一點影響,須要稍做處理。詳細過程見代碼:class
#include <iostream> #include <memory> #include <new> class Boxes{ private: //用於構建雙向鏈表. std::unique_ptr<int[]> left; //當下標爲i的時候i的左側的內容. std::unique_ptr<int[]> right; //當下標爲i的時候i的右側的內容. bool flag; //判斷是否反轉了鏈表. unsigned int suffix; unsigned int X; unsigned int Y; void link(const int& lh, const int& rh)noexcept; public: Boxes(const std::size_t& size); ~Boxes() = default; void moveBox(); }; Boxes::Boxes(const std::size_t& size)try :left(nullptr), right(nullptr), flag(false) { if(size == 0){ throw std::bad_alloc(); } (this->left).reset(new int[size+1]); (this->right).reset(new int[size+1]); //構建雙向鏈表. for(std::size_t i=1; i<=size; ++i){ (this->left)[i] = i-1; (this->right)[i] = (i+1)%(size+1); } (this->right)[0] = 1; (this->left)[0] = size; /*for(std::size_t i=0; i<=size; ++i){ std::cout<< "[" << i << "]:" << (this->left)[i] << " "; } std::cout<< std::endl; for(std::size_t i=0; i<=size; ++i){ std::cout<< "[" << i << "]:" << (this->right)[i] << " "; }*/ }catch(const std::bad_alloc& error){ std::cout<< "fail to allocate" <<std::endl; } void Boxes::link(const int& lh, const int& rh)noexcept { (this->left)[rh] = lh; (this->right)[lh] = rh; } void Boxes::moveBox() { while( std::cin>>(this->suffix) ){ if((this->suffix) == 4){ (this->flag) = !(this->flag); //若是等於4那麼反轉. }else{ std::cin>>(this->X); std::cin>>(this->Y); //在未被反轉過的狀況下盒子Y的右側正好是盒子X. if((this->suffix) == 3 && (this->right)[this->Y] == this->X) std::swap(this->X, this->Y); //判斷是否在須要被交換的節點不相鄰的狀況下,且已經執行了逆序操做的狀況下 使原來的左邊變右邊. if((this->suffix) != 3 && (this->flag) == true) (this->suffix) = 3 - (this->suffix); //判斷反轉後是否盒子X正好位於盒子Y的左側. if((this->suffix) == 1 && (this->X) == (this->left)[this->Y]); //判斷反轉後是否盒子X正好位於盒子Y的右側. if((this->suffix) == 2 && (this->X) == (this->right)[this->Y]); int lX=(this->left)[this->X]; //得到座標爲X的左側的數據. int rX=(this->right)[this->X]; //得到座標爲X的右側數據. int lY=(this->left)[this->Y]; //得到座標爲Y的左側數據. int rY=(this->right)[this->Y]; //得到座標爲Y的右側數據. if((this->suffix) == 1){ //將X座標處的數據移到Y座標處數據的左邊. this->link(lX, rX); this->link(lY, (this->X)); this->link((this->X), (this->Y)); }else if((this->suffix) == 2){ //將X座標處的數據移動到Y的右邊. this->link(lX, rX); this->link((this->Y), (this->X)); this->link((this->X), lY); }else if((this->suffix) == 3){ //交換座標X處和座標Y處的數據. if((this->left)[this->X] == Y){ //X和Y相鄰. this->link(lX, (this->X)); this->link((this->Y), (this->X)); this->link((this->X), rY); }else{ this->link(lX, (this->Y)); this->link((this->Y), rX); this->link(lY, (this->X)); this->link((this->X), rY); } } } } } int main() { Boxes box(3); box.moveBox(); return 0; }