Given is a grid of size N \times N. It contains numbers from 1 to N^2. You start at the cell numbered 1, move to 2, then to 3, and so on up till N^2. Report the total manhattan distance traversed in doing so.
EXPLANATION:
Subtask 1 and 2
We keep an array M of size N^2 and a variable Dist = 0. M[i] stores the coordinates of number i in the grid. Let M[i].x denote the x-coordinate and M[i].y denote the y-coordinate. Dist stores the total distance moved. Once array M has been filled, we can iterate from i\,=\,1 to N^2 and keep increasing the variable Dist by the distance moved while going from i-1 to i:
Note that Manhattan distance between i and i-1 is being added to Dist. This is because the question says that you can only move from one cell to another if the latter shares an edge with the former.
Why wouldn’t this code run on the CodeChef IDE? It ran without problems on two other online IDE’s, but it gave a runtime error on the CodeChef IDE.
#include <iostream>
using namespace std;
int main()
{
unsigned int T;
cin >> T;
unsigned int** mat;
unsigned int N, num, lastNum, moves;
unsigned int ypos, nextYpos, xpos, nextXpos;
bool breakCheck;
for (unsigned int tnum=0; tnum<T; tnum++)
{
cin >> N;
moves = 0;
mat = new unsigned int*[N];
for (unsigned int i=0; i<N; i++)
{
mat[i] = new unsigned int[N];
}
for (unsigned int y=0; y<N; y++)
{
for (unsigned int x=0; x<N; x++)
{
cin >> num;
mat[y][x] = num;
}
}
lastNum = N * N;
num = 0; moves = 0;
breakCheck = false;
for (unsigned int y=0; y<N; y++)
{
for (unsigned int x=0; x<N; x++)
{
if (mat[y][x]==1)
{
ypos = y; xpos = x;
breakCheck = true;
num = 1;
break;
}
}
if (breakCheck)
{
break;
}
}
do
{
breakCheck = false;
num = num+1;
for (unsigned int y=0; y<N; y++)
{
for (unsigned int x=0; x<N; x++)
{
if (mat[y][x]==num)
{
nextYpos = y; nextXpos = x;
breakCheck = true;
break;
}
}
if (breakCheck)
{
break;
}
}
if (nextYpos<ypos)
{
moves += (ypos - nextYpos);
}
else
{
moves += (nextYpos - ypos);
}
if (nextXpos<xpos)
{
moves += (xpos - nextXpos);
}
else
{
moves += (nextXpos - xpos);
}
ypos = nextYpos; xpos = nextXpos;
} while (num!=lastNum);
for (unsigned int i=0; i<N; i++)
{
delete[] mat[i];
}
delete[] mat;
cout << moves;
if ((tnum+1)!=T)
{
cout << '\n';
}
}
return 0;
I could solve the problem with cin instead of using scanf in C++;
I did this by adding
std::ios::sync_with_stdio(false);
to the program. The speed difference in cin and scanf is largely due to the iostream I/O functions maintaining synchronization with the C I/O functions. It turns out that this internal syncing/flushing is what normally slows down iostream I/O. If we’re not mixing cstdio and iostream, we can turn it off, and then iostream is fastest.
#include<bits/stdc++.h>
using namespace std;
int r[250005],c[250005];
int main()
{
int t;
scanf("%d",&t);
while(t–)
{
int n;
long long ans=0;
scanf("%d",&n);
int ar[505][505],i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&ar[i][j]);
r[ar[i][j]]=i;
c[ar[i][j]]=j;
}
}
for(i=2;i<=n*n;i++)
ans+=(abs(r[i]-r[i-1])+abs(c[i]-c[i-1]));
cout<<ans<<endl;
}
return 0;
}