http://acm.hdu.edu.cn/showproblem.php?pid=4286
思路:左边、右边为栈,中间为双端队列
栈空间的限制
这题如果将 n*50w 的 int 数组放在栈中,会报出“stack overflow”的错误,关于栈空间的大小限制 Linux 平台可用如下命令查看:
ulimit -a
具体讨论见:
http://www.cs.nyu.edu/exact/core/doc/stackOverflow.txt
实现一:数组模拟栈和双端队列
/*
* hdu 4286
* http://acm.hdu.edu.cn/showproblem.php?pid=4286
* 【栈】【双端队列】
* 自己实现栈和双端队列(不用 STL)
*/
#include <cstdio>
#include <cstdlib>
using namespace std;
#define MAX 500002
#define POSITIVE 1
#define MAX_CMD 20
int arriDeque[4*MAX];
int arriStackL[2*MAX], arriStackR[2*MAX];
int arriPrint[2*MAX]; // 临时存储用于输出
int main()
{
int iHead, iTail; // 双端队列的首和尾
int iTmpHead;
int iDirect; // 双端队列的方向
int iTopL, iTopR; // 左边栈和右边栈的顶指针
int iCases, iNums, iLeft, iRight, iCmds, iData;
char szCmd[MAX_CMD];
char *pszTmp;
int i;
int j;
scanf("%d", &iCases);
while (iCases--)
{
iDirect = POSITIVE;
iTmpHead = 2*MAX;
scanf("%d", &iNums);
for (i = 0; i < iNums; ++i)
{
scanf("%d", &arriDeque[iTmpHead+i]);
}
scanf("%d%d", &iLeft, &iRight);
iHead = iTmpHead + iLeft - 1;
iTail = iTmpHead + iRight - 1;
iTopL = -1;
iTopR = -1;
for (i = 1; i < iLeft; ++i)
{
arriStackL[++iTopL] = arriDeque[iTmpHead+i-1];
}
for (i = iNums; i > iRight; --i)
{
arriStackR[++iTopR] = arriDeque[iTmpHead+i-1];
}
// 处理命令
scanf("%d", &iCmds);
getchar(); // 吸收 '\n', 防止被 fgets 吸入
while (iCmds--)
{
fgets(szCmd, MAX_CMD, stdin);
switch (szCmd[0])
{
case 'M':
if ('L' == szCmd[4]) // MoveLeft
{
if ('L' == szCmd[9]) // MoveLeft L
{
if (POSITIVE == iDirect)
{
arriDeque[--iHead] = arriStackL[iTopL--];
}
else
{
arriDeque[++iTail] = arriStackL[iTopL--];
}
}
else if ('R' == szCmd[9]) // MoveLeft R
{
if (POSITIVE == iDirect)
{
arriStackR[++iTopR] = arriDeque[iTail--];
}
else
{
arriStackR[++iTopR] = arriDeque[iHead++];
}
}
}
else if ('R' == szCmd[4]) // MoveRight
{
if ('L' == szCmd[10]) // MoveRight L
{
if (POSITIVE == iDirect)
{
arriStackL[++iTopL] = arriDeque[iHead++];
}
else
{
arriStackL[++iTopL] = arriDeque[iTail--];
}
}
else if ('R' == szCmd[10]) // MoveRight R
{
if (POSITIVE == iDirect)
{
arriDeque[++iTail] = arriStackR[iTopR--];
}
else
{
arriDeque[--iHead] = arriStackR[iTopR--];
}
}
}
break;
case 'I':
pszTmp = szCmd + 9;
iData = atoi(pszTmp);
if ('L' == szCmd[7]) // Insert L X
{
if (POSITIVE == iDirect)
{
arriDeque[--iHead] = iData;
}
else
{
arriDeque[++iTail] = iData;
}
}
else if ('R' == szCmd[7]) // Insert R X
{
if (POSITIVE == iDirect)
{
arriDeque[++iTail] = iData;
}
else
{
arriDeque[--iHead] = iData;
}
}
break;
case 'D':
if ('L' == szCmd[7]) // Delete L
{
if (POSITIVE == iDirect)
{
++iHead;
}
else
{
--iTail;
}
}
else if ('R' == szCmd[7]) // Delete R
{
if (POSITIVE == iDirect)
{
--iTail;
}
else
{
++iHead;
}
}
break;
case 'R': // Reverse
iDirect = !iDirect;
break;
default:
break;
}
}
// 输出结果
j = 0;
for (i = 0; i <= iTopL; ++i)
{
arriPrint[j++] = arriStackL[i];
}
if (POSITIVE == iDirect)
{
for (i = iHead; i <= iTail; ++i)
{
arriPrint[j++] = arriDeque[i];
}
}
else
{
for (i = iTail; i >= iHead; --i)
{
arriPrint[j++] = arriDeque[i];
}
}
for (i = iTopR; i >= 0; --i)
{
arriPrint[j++] = arriStackR[i];
}
--j;
for (i = 0; i < j; ++i)
{
printf("%d ", arriPrint[i]);
}
printf("%d\n", arriPrint[i]);
}
return 0;
}
实现二:STL
/*
* hdu 4286
* http://acm.hdu.edu.cn/showproblem.php?pid=4286
* 【栈】【双端队列】【STL】
* STL 实现
*/
#include <iostream>
#include <string>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
using namespace std;
#define MAX 500002
#define POSITIVE 1
#define MAX_CMD 20
int arriTmp[2*MAX];
int main()
{
deque<int> deqDeque;
stack<int> stkStackL, stkStackR;
int iDirect; // 双端队列的方向
int iCases, iNums, iLeft, iRight, iCmds, iData;
char szCmd[MAX_CMD];
char *pszTmp;
int i, j, iSize;
scanf("%d", &iCases);
while (iCases--)
{
/* 这里不需要手动清空 stack */
deqDeque.clear();
iDirect = POSITIVE;
scanf("%d", &iNums);
for (i = 0; i < iNums; ++i)
{
scanf("%d", &arriTmp[i]);
}
scanf("%d%d", &iLeft, &iRight);
for (i = 1; i < iLeft; ++i)
{
stkStackL.push(arriTmp[i-1]);
}
for (i = iLeft; i <= iRight; ++i)
{
deqDeque.push_back(arriTmp[i-1]);
}
for (i = iNums; i > iRight; --i)
{
stkStackR.push(arriTmp[i-1]);
}
// 处理命令
scanf("%d", &iCmds);
getchar(); // 吸收 '\n', 防止被 fgets 吸入
while (iCmds--)
{
fgets(szCmd, MAX_CMD, stdin);
switch (szCmd[0])
{
case 'M':
if ('L' == szCmd[4]) // MoveLeft
{
if ('L' == szCmd[9]) // MoveLeft L
{
if (POSITIVE == iDirect)
{
deqDeque.push_front(stkStackL.top());
}
else
{
deqDeque.push_back(stkStackL.top());
}
stkStackL.pop();
}
else if ('R' == szCmd[9]) // MoveLeft R
{
if (POSITIVE == iDirect)
{
stkStackR.push(deqDeque.back());
deqDeque.pop_back();
}
else
{
stkStackR.push(deqDeque.front());
deqDeque.pop_front();
}
}
}
else if ('R' == szCmd[4]) // MoveRight
{
if ('L' == szCmd[10]) // MoveRight L
{
if (POSITIVE == iDirect)
{
stkStackL.push(deqDeque.front());
deqDeque.pop_front();
}
else
{
stkStackL.push(deqDeque.back());
deqDeque.pop_back();
}
}
else if ('R' == szCmd[10]) // MoveRight R
{
if (POSITIVE == iDirect)
{
deqDeque.push_back(stkStackR.top());
}
else
{
deqDeque.push_front(stkStackR.top());
}
stkStackR.pop();
}
}
break;
case 'I':
pszTmp = szCmd + 9;
iData = atoi(pszTmp);
if ('L' == szCmd[7]) // Insert L X
{
if (POSITIVE == iDirect)
{
deqDeque.push_front(iData);
}
else
{
deqDeque.push_back(iData);
}
}
else if ('R' == szCmd[7]) // Insert R X
{
if (POSITIVE == iDirect)
{
deqDeque.push_back(iData);
}
else
{
deqDeque.push_front(iData);
}
}
break;
case 'D':
if ('L' == szCmd[7]) // Delete L
{
if (POSITIVE == iDirect)
{
deqDeque.pop_front();
}
else
{
deqDeque.pop_back();
}
}
else if ('R' == szCmd[7]) // Delete R
{
if (POSITIVE == iDirect)
{
deqDeque.pop_back();
}
else
{
deqDeque.pop_front();
}
}
break;
case 'R': // Reverse
iDirect = !iDirect;
break;
default:
break;
}
}
// 输出结果
deque<int>::iterator it;
deque<int>::reverse_iterator rit;
j = 0;
iSize = stkStackL.size();
for (i = iSize - 1; i >= 0; --i)
{
arriTmp[i] = stkStackL.top();
stkStackL.pop();
}
j += iSize;
if (POSITIVE == iDirect)
{
for (it = deqDeque.begin(); it != deqDeque.end(); ++it)
{
arriTmp[j++] = *it;
}
}
else
{
for (rit = deqDeque.rbegin(); rit != deqDeque.rend(); ++rit)
{
arriTmp[j++] = *rit;
}
}
iSize = stkStackR.size();
for (i = 0; i < iSize; ++i)
{
arriTmp[j+i] = stkStackR.top();
stkStackR.pop();
}
j += i;
for (i = 0; i < j - 1; ++i)
{
printf("%d ", arriTmp[i]);
}
printf("%d\n", arriTmp[i]);
}
return 0;
}
完全 C++ 风格(因为输入输出用 C++ 方式,提交超时)
/*
* 输入全部用 C++ 方式:超时
*/
#include <iostream>
#include <string>
#include <deque>
#include <stack>
#include <cstdlib>
using namespace std;
#define MAX 500002
#define POSITIVE 1
int arriTmp[2*MAX];
int main()
{
deque<int> deqDeque;
stack<int> stkStackL, stkStackR;
int iDirect; // 双端队列的方向
int iCases, iNums, iLeft, iRight, iCmds, iData;
string strCmd;
int i, j, iSize;
cin >> iCases;
while (iCases--)
{
/* 这里不需要手动清空 stack */
deqDeque.clear();
iDirect = POSITIVE;
cin >> iNums;
for (i = 0; i < iNums; ++i)
{
cin >> arriTmp[i];
}
cin >> iLeft >> iRight;
for (i = 1; i < iLeft; ++i)
{
stkStackL.push(arriTmp[i-1]);
}
for (i = iLeft; i <= iRight; ++i)
{
deqDeque.push_back(arriTmp[i-1]);
}
for (i = iNums; i > iRight; --i)
{
stkStackR.push(arriTmp[i-1]);
}
// 处理命令
cin >> iCmds;
cin.get(); // 吸收 '\n', 防止被 fgets 吸入
while (iCmds--)
{
getline(cin, strCmd);
switch (strCmd[0])
{
case 'M':
if ('L' == strCmd[4]) // MoveLeft
{
if ('L' == strCmd[9]) // MoveLeft L
{
if (POSITIVE == iDirect)
{
deqDeque.push_front(stkStackL.top());
}
else
{
deqDeque.push_back(stkStackL.top());
}
stkStackL.pop();
}
else if ('R' == strCmd[9]) // MoveLeft R
{
if (POSITIVE == iDirect)
{
stkStackR.push(deqDeque.back());
deqDeque.pop_back();
}
else
{
stkStackR.push(deqDeque.front());
deqDeque.pop_front();
}
}
}
else if ('R' == strCmd[4]) // MoveRight
{
if ('L' == strCmd[10]) // MoveRight L
{
if (POSITIVE == iDirect)
{
stkStackL.push(deqDeque.front());
deqDeque.pop_front();
}
else
{
stkStackL.push(deqDeque.back());
deqDeque.pop_back();
}
}
else if ('R' == strCmd[10]) // MoveRight R
{
if (POSITIVE == iDirect)
{
deqDeque.push_back(stkStackR.top());
}
else
{
deqDeque.push_front(stkStackR.top());
}
stkStackR.pop();
}
}
break;
case 'I':
iData = atoi(strCmd.substr(9).c_str());
if ('L' == strCmd[7]) // Insert L X
{
if (POSITIVE == iDirect)
{
deqDeque.push_front(iData);
}
else
{
deqDeque.push_back(iData);
}
}
else if ('R' == strCmd[7]) // Insert R X
{
if (POSITIVE == iDirect)
{
deqDeque.push_back(iData);
}
else
{
deqDeque.push_front(iData);
}
}
break;
case 'D':
if ('L' == strCmd[7]) // Delete L
{
if (POSITIVE == iDirect)
{
deqDeque.pop_front();
}
else
{
deqDeque.pop_back();
}
}
else if ('R' == strCmd[7]) // Delete R
{
if (POSITIVE == iDirect)
{
deqDeque.pop_back();
}
else
{
deqDeque.pop_front();
}
}
break;
case 'R': // Reverse
iDirect = !iDirect;
break;
default:
break;
}
}
// 输出结果
deque<int>::iterator it;
deque<int>::reverse_iterator rit;
j = 0;
iSize = stkStackL.size();
for (i = iSize - 1; i >= 0; --i)
{
arriTmp[i] = stkStackL.top();
stkStackL.pop();
}
j += iSize;
if (POSITIVE == iDirect)
{
for (it = deqDeque.begin(); it != deqDeque.end(); ++it)
{
arriTmp[j++] = *it;
}
}
else
{
for (rit = deqDeque.rbegin(); rit != deqDeque.rend(); ++rit)
{
arriTmp[j++] = *rit;
}
}
iSize = stkStackR.size();
for (i = 0; i < iSize; ++i)
{
arriTmp[j+i] = stkStackR.top();
stkStackR.pop();
}
j += i;
for (i = 0; i < j - 1; ++i)
{
cout << arriTmp[i] << " ";
}
cout << arriTmp[i] << endl;
}
return 0;
}