Reputation: 106
I've just solved a problem on SPOJ, I do DFS and use STL stack instead of recursive, I got TLE. Then i use array stack instead of STL stack and got Accepted.
The problem is : Give an n*n table, each square have a number. First, you can start at any square, choose a number K.Then you can go to squares that have a common edge with the square you stand, and abs( number on that square - number on the square you stand) == K. What is the biggest area that you can go ?
This is my solution :
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <utility>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
#define maxn 1010
int n, a[maxn][maxn],visited[maxn][maxn], direction[5][3],cnt,anscnt,dd[1000010],dc[1000010],k[1000010];
bool Free[maxn][maxn][5];
/*void visit(int d,int c,int dif) {
stack<int> dd,dc,k;
dd.push(d);
dc.push(c);
k.push(1);
visited[d][c]=dif;
cnt = 0;
while (!dd.empty()) {
int ud = dd.top(), uc = dc.top() , i = k.top();
k.pop();
for (;i<=4;i++)
if (Free[ud][uc][i]) {
int vd = ud+direction[i][1], vc = uc + direction[i][2];
if ((vd==0) or (vc==0) or (vd>n) or (vc>n)) continue;
if ((visited[vd][vc]==dif) or (abs(a[vd][vc]-a[ud][uc])!=dif)) continue;
if (Free[vd][vc][5-i]==false) continue;
visited[vd][vc]=dif;
Free[vd][vc][5-i]=false;
Free[ud][uc][i]=false;
k.push(i+1);
dd.push(vd);
dc.push(vc);
k.push(1);
break;
}
if (i==5) {
cnt++;
cout << ud << ' ' << uc << ' ' << dd.top() << ' ' << dc.top() << ' ' << dd.size() << '\n';
dd.pop(); dc.pop();
}
}
if (cnt > anscnt) {anscnt = cnt;}
} */
void visit(int d,int c,int dif) {
int topdd=0, topdc=0, topk=0;
dd[++topdd]=d;
dc[++topdc]=c;
k[++topk]=1;
visited[d][c]=dif;
cnt = 0;
while (topdd>0) {
int ud = dd[topdd], uc = dc[topdc] , i = k[topk];
topk--;
for (;i<=4;i++)
if (Free[ud][uc][i]) {
int vd = ud+direction[i][1], vc = uc + direction[i][2];
if ((vd==0) or (vc==0) or (vd>n) or (vc>n)) continue;
if ((visited[vd][vc]==dif) or (abs(a[vd][vc]-a[ud][uc])!=dif)) continue;
if (Free[vd][vc][5-i]==false) continue;
visited[vd][vc]=dif;
Free[vd][vc][5-i]=false;
Free[ud][uc][i]=false;
k[++topk]=(i+1);
dd[++topdd]=(vd);
dc[++topdc]=(vc);
k[++topk]=(1);
break;
}
if (i==5) {
cnt++;
topdd--; topdc--;
}
}
if (cnt > anscnt) {anscnt = cnt;}
}
int main()
{
std::ios_base::sync_with_stdio(false);
anscnt = 1;
direction[1][1] = -1; direction[1][2] = 0;
direction[2][1] = 0; direction[2][2] = 1;
direction[3][1] = 0; direction[3][2] = -1;
direction[4][1] = 1; direction[4][2] = 0;
cin >> n;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) cin >> a[i][j];
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) visited[i][j]=-1;
memset(Free,true,sizeof(Free));
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) {
if (i>1) visit(i,j,abs(a[i][j]-a[i-1][j]));
if (j<n) visit(i,j,abs(a[i][j]-a[i][j+1]));
if (j>1) visit(i,j,abs(a[i][j]-a[i][j-1]));
if (i<n) visit(i,j,abs(a[i][j]-a[i+1][j]));
}
cout << anscnt;
}
When n = 1000, and all square in table = 0, STL stack is more than 2s and array stack is less than 1s. So i think STL implementation of stack is slower than implementing stack by array. Queue, deque also can be implemented by array too.
Why is STL implementation slower and should i implement them by array to improve performane ?
Upvotes: 0
Views: 262
Reputation: 3336
As usual you should always use direct memory access (like arrays) in simple cases or implement your own data structure for complex cases for better perfomance. Std containers have checks, inderections and throw exceptions that decrease memory access perfomance. Moreover in your algorithm in 'stack' version you use methods to increase/decrease stack size, that can (but not must) cause large amout of memory allocation/deallocation that also leads to perfomance issues.
Upvotes: 1