Page 1 of 2

### 10426 - Knights' Nightmare

Posted: Mon Jan 13, 2003 8:33 pm
I can find a test where my program gets WA. Please, help me!!

[pascal]Program p10426;

Const MaxN = 16;
MaxR = 1000;

Type InfType = Array[1..MaxN,1..MaxN]of Byte;

Var R,C,i,j : Integer;
K : Array[1..4,1..2] of Integer;
Inf : Array[1..4,0..1]of InfType;
Mr,Mc : Integer;
test : Integer;
S : String;

Procedure FillK(ID : Integer);
Var x,y,p,t : Integer;
order : Array[1..MaxR,1..2] of Integer;
b,bc,e,ec : Integer;
procedure check(dx,dy : integer);
var yy : integer;
begin
if (x+dx<1)or(x+dx>R) then exit;
if (y+dy<1)or(y+dy>C) then exit;
if inf[id][0][x+dx,y+dy]<=p then exit;
inf[id][0][x+dx,y+dy]:=p;
if not((x+dx=Mr) and (y+dy=Mc)) then begin
if e + ec > MaxR then yy := e + ec - MaxR else yy := e + ec;
order[yy,1]:=x+dx;
order[yy,2]:=y+dy;
ec := ec + 1;
end;
end;
procedure check2(dx,dy : integer);
var yy : integer;
begin
if (x+dx<1)or(x+dx>R) then exit;
if (y+dy<1)or(y+dy>C) then exit;
if inf[id][0][x+dx,y+dy]<=p then exit;
inf[id][0][x+dx,y+dy]:=p;
if e + ec > MaxR then yy := e + ec - MaxR else yy := e + ec;
order[yy,1]:=x+dx;
order[yy,2]:=y+dy;
ec := ec + 1;
end;
begin
(* fill without monster *)
fillchar(inf[id][0], sizeof(inf[id][0]), 255);
inf[id][0][k[ID,1], k[ID,2]] := 0;
order[1,1] := k[ID,1];
order[1,2] := k[ID,2];
b := 1; bc := 1;
e := 2; ec := 0;
p := 0;
while bc > 0 do begin
p := p + 1;
for t := 1 to bc do begin
x := order[b,1];
y := order[b,2];
check(-2,-1);
check(-2,1);
check(-1,-2);
check(-1,2);
check(1,-2);
check(1,2);
check(2,-1);
check(2,1);
b := b + 1;
if b = MaxR + 1 then b := 1;
end;
bc := ec;
b := e;
e := e + ec;
if e > MaxR then e := e - MaxR;
ec := 0;
end;
(* fill with monsters *)
inf[id][1] := inf[id][0];
order[1,1] := Mr;
order[1,2] := Mc;
b := 1; bc := 1;
e := 2; ec := 0;
p := inf[id][0][Mr,Mc];
if p = 255 then exit;
while bc > 0 do begin
p := p + 1;
for t := 1 to bc do begin
x := order[b,1];
y := order[b,2];
check2(-2,-1);
check2(-2,1);
check2(-1,-2);
check2(-1,2);
check2(1,-2);
check2(1,2);
check2(2,-1);
check2(2,1);
b := b + 1;
if b = MaxR + 1 then b := 1;
end;
bc := ec;
b := e;
e := e + ec;
if e > MaxR then e := e - MaxR;
ec := 0;
end;
end;

function getit(x,y,id : integer) : integer;
var r,i : integer;
begin
r:=0;
for i:=1 to 4 do if i <> id then begin
if inf[0][x,y]=255 then begin getit:=-1; exit; end else
r:=r+inf[0][x,y];
end;
if inf[id][1][x,y]=255 then begin getit:=-1; exit; end;
r:=r+inf[id][1][x,y];
getit:=r;
end;

function getitxy(x,y : integer) : integer;
var i,r,b : integer;
begin
r:=10000;
for i:=1 to 4 do begin
b:=getit(x,y,i);
if (b<>-1) and (b<r) then r:=b;
end;
if r<>10000 then getitxy:=r else getitxy:=-1;
end;

procedure getans;
var i,j : integer;
b,rr : integer;
begin
b:=10000;
for i:=1 to R do
for j:=1 to C do
if not((i=Mr)and(j=Mc)) then begin
rr:=getitxy(i,j);
if (rr<>-1) and (rr<b) then b:=rr;
end;
if b=10000 then Writeln('Meeting is impossible.') else
Writeln('Minimum time required is ',b,' minutes.');
end;

begin
test:=0;
While Not Eof do begin
test:=test+1;
Writeln('Set#',test);
for i := 1 to 4 do for j := 1 to 2 do Read(K[i,j]);
for i := 1 to 4 do FillK(i);
getans;
end;
end.[/pascal]

### Yes! I fix it!!!!!

Posted: Mon Jan 13, 2003 8:49 pm
Thanks to all who tries to help me
I get it. I get Accepted

Posted: Thu Jan 16, 2003 11:36 am
I can't get pass the monster part. Can someone give me a hint on how to handle the monster?

Posted: Fri Jan 17, 2003 1:48 pm
You have to find such a position where everyone can gather and the cell with monster would be visited only once. This can be done using BFS for each of the four knights and to allow only one of them to step onto the monster's cell.

Maybe I explained not very well - if so ask me details.

Good luck.

Posted: Sat Jan 18, 2003 6:18 am
Thanks anyhow!

I actually knew what to do, but thought there was some special property of chess I wasn't aware of involving skipping a square with knights or something.

And then I tried using a brute-force (in calculating the minimum) and used Bound and Branch for calcuation of distance, but that went too slowly. So I used BFS and it did the job a lot faster. I guess when in doubt, brute force!

Posted: Thu Jan 30, 2003 6:04 am

I have read the pascal program,
for each set , he has performed BFS for 8 times.
My method need only 5 times, I think It can reduce the run time.

### 10426

Posted: Mon Mar 17, 2003 6:50 pm

(give me some test cases at least if you don't feel like reading the code)

[c]/* @JUDGE_ID: ??????? 10426 C Knights' Nightmare */

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 16

#define EMPTY (n_jmp)(~0)

#define MIN(a,b) ((a)<(b)?(a):(b))

typedef unsigned short int n_jmp;

n_jmp knightland[2][4][MAXSIZE * MAXSIZE], newland[MAXSIZE * MAXSIZE];

typedef struct { char i,j; n_jmp jmps; } square;

square kings[4], monster;

int land_Nrow, land_Ncol;

typedef square element;

typedef struct {
int first, next;
int size;
element *tab;
} queue;

queue *myqueue;

/* eight possible moves for a chess' knight */
const char moves_i[8] = { 1, -1, 2, -2, 1, -1, 2, -2};
const char moves_j[8] = { 2, 2, 1, 1, -2, -2, -1, -1};

/*--------- queue functions ----------*/

queue *make_queue(int size)
{
queue *q = malloc(sizeof(queue));
if (q == NULL)
return q;
q->size = size;
q->tab = malloc((size+1) * sizeof(element));
if (q->tab == NULL)
{
free(q);
return NULL;
}
q->first = 0;
q->next = 0;
return q;
}

char enqueue(queue *q, element *e)
{
if ((q->next+1)%(q->size+1) == q->first)
return 0; /* queue full */
q->tab[q->next] = *e;
q->next = (q->next+1)%(q->size+1);
return 1;
}

char dequeue(queue *q, element *e)
{
if (q->next == q->first)
return 0; /* queue empty */
*e = q->tab[q->first];
q->first = (q->first+1)%(q->size+1);
return 1;
}

void empty(queue *q)
{
q->next = q->first;
}

void destroy_queue(queue *q)
{
free(q->tab);
free(q);
}

/*-------------------------------------------*/

void init()
{
if (!(myqueue = make_queue(MAXSIZE*MAXSIZE)))
exit(EXIT_FAILURE);
}

/*-------------------------------------------*/

int get_data()
/* return set # */
{
char buffer[10];
int i;
int a,b;
int set_no;
if (scanf("%s",buffer) != 1)
return 0;
set_no = atoi(buffer+4);
scanf("%d %d", &land_Nrow, &land_Ncol);
for (i=0; i<4; i++)
{
scanf("%d %d", &a, &b);
kings.i = (char)(a-1);
kings.j = (char)(b-1);
}
scanf("%d %d", &a, &b);
monster.i = (char)(a-1);
monster.j = (char)(b-1);
return set_no;
}
/*-------------------------------------------*/

void make_way(square *king, n_jmp *land, char avoid_monster)
{
int i;
const char *movesi, *movesj;
square mysquare, newsquare;
memset(land, ~0, sizeof(n_jmp) * land_Nrow * land_Ncol);
king->jmps = 0;
land[king->i * land_Nrow + king->j] = 0;
enqueue(myqueue, king);
/* avoid monster ??? */
if (avoid_monster)
land[monster.i * land_Nrow + monster.j] = MONSTERSSQUARE;
while (dequeue(myqueue, &mysquare))
{
movesi = moves_i;
movesj = moves_j;
newsquare.jmps = mysquare.jmps + 1;
/* eigth possible moves */
for (i=0; i<8; i++)
{
newsquare.i = mysquare.i + *movesi++;
newsquare.j = mysquare.j + *movesj++;
if (newsquare.i >= 0 && newsquare.i < land_Nrow
&& newsquare.j >= 0 && newsquare.j < land_Ncol
&& land[newsquare.i * land_Nrow + newsquare.j] == EMPTY)
{
land[newsquare.i * land_Nrow + newsquare.j] = newsquare.jmps;
enqueue(myqueue, &newsquare);
}
}
}
}

/*-------------------------------------------*/

void solve(int set_no)
{
int i,j,k;
square mysquare, newsquare;
n_jmp min_meet = EMPTY;
n_jmp *land[4];
n_jmp jmps;
for (i=0; i<4; i++)
for (j=0; j<2; j++)
make_way(&kings, knightland[j], j);
memset(newland, ~0, sizeof(n_jmp) * land_Nrow * land_Ncol);
for (k=0; k<4; k++)
{
land[0] = knightland[1][0];
land[1] = knightland[1][1];
land[2] = knightland[1][2];
land[3] = knightland[1][3];
land[k] = knightland[0][k];
for(i=0; i< land_Nrow * land_Ncol; i++)
{
jmps = land[0] + land[1] + land[2][i] + land[3][i];
newland[i] = MIN(newland[i], jmps);
min_meet = MIN(min_meet, newland[i]);
}
}
printf("set#%d\n", set_no);
if (min_meet == EMPTY)
printf("Meeting is impossible.\n");
else
printf("Minimum time required is %u minute%s.\n", min_meet, (min_meet == 1 || min_meet == 0)?"":"s");
}
/*-------------------------------------------*/

void clean()
{
destroy_queue(myqueue);
}
/*-------------------------------------------*/

int main()
{
int set_no;
init();
while(set_no = get_data())
solve(set_no);
clean();
return EXIT_SUCCESS;
}
[/c]

### nevermind

Posted: Mon Mar 17, 2003 7:01 pm
nevermind

i just go accepted PE.
found my error: i wrote several times
stuff.i * land_Nrow + stuff.j
stuff.i * land_Ncol + stuff.j

### ID !!

Posted: Mon Mar 17, 2003 7:30 pm
You shouldn't give your ID on this forum.

A+.
Olivier.

### 10426: something odd WA/PE

Posted: Tue May 13, 2003 5:18 am

Code: Select all

``````epsilon0 (Posted: Mon Mar 17, 2003 5:50 pm
Post subject: help with 10426 (wa))

posted his code for 10426. It ended like this:

printf("set#%d\n", set_no);
if (min_meet == EMPTY)
printf("Meeting is impossible.\n");
else
printf("Minimum time required is %u minute%s.\n",
min_meet,
(min_meet == 1 || min_meet == 0)?"":"s"); }

The problem states:

"The first line should contain the string "Set#n",
where n is the set number. The second line should give
the minimum time in minutes needed to reach a square
(in format shown below)"

And the format show below, in the sample output is:

Minimum time required is 6 minutes.

So obviously epsilon0 got WA because he printed the wrong

But then in the very next posting he says:

"nevermind
i just go accepted PE."

What on earth?
Printing completely the wrong string has never been
considered a presentation error. The difference between
"minute" and "minutes" has always been enough to

Have the rules changed, or is there something really
odd going on?

``````

### Re: 10426: something odd WA/PE

Posted: Tue May 13, 2003 11:57 am
Cletus wrote:[c]
printf("Minimum time required is %u minute%s.\n",
min_meet,
(min_meet == 1 || min_meet == 0)?"":"s");
[/c]
this is equivalent to :
[c]printf("Minimum time required is %u minute",min_meet);
if(min_meet>1)
printf("s");
printf(".\n");
[/c]

### I don't think you understood the question.

Posted: Tue May 13, 2003 7:46 pm

Code: Select all

``````I don't think you understood the question.

I pointed out that code that does not do what the
problem required, i.e. follow the form of
"Minimum time required is 6 minutes."
could get PE instead of WA.

The code posted prints "minute" instead of "minutes"
when the number is 0 or 1 (I do know what %s does),
when the question says that "minutes" should always
be printed. Adding extra characters was always a
reason for WA, not PE. Also, the posted code printed

So either there is something strange about the judging
system, or the original poster somehow guessed that
the instructions had to be disobeyed to get accepted.
I know that the UVA problem set has had many
instances of instructions that had to be disobeyed in
ways that we could only guess at, but this one is just
too much.

OK, we could perhaps guess that 1 should be followed
by "minute" instead of "minutes", but not 0. How could
anyone who guessed at substituting incorrect English
for what the instructions state possibly be surprised
by a WA?

The question is: how could code that disobeys the
instructions for the output in that way possibly get
accepted/PE?

``````

Posted: Sat Dec 25, 2004 8:50 pm
There's probably no input where a knight starts at the same position as another knight. Not explicitly stated, but does seem to be an additional constraint.

The PE is more likely due to 'set#1'. I think they can turn case-sensitivity on a per problem basis, but not entirely certain of that.

### Re: 10426 - Knights' Nightmare

Posted: Sat Dec 12, 2009 8:05 am
Can anyone give me some critical test cases? I am getting WA.... Here is my code:

Code: Select all

``AC``

### Re: 10426: something odd WA/PE

Posted: Fri Apr 30, 2010 4:00 pm
bery olivier wrote:
Cletus wrote:[c]
printf("Minimum time required is %u minute%s.\n",
min_meet,
(min_meet == 1 || min_meet == 0)?"":"s");
[/c]
this is equivalent to :
[c]printf("Minimum time required is %u minute",min_meet);
if(min_meet>1)
printf("s");
printf(".\n");
[/c]
Never confused.
The AC output format is:

Code: Select all

``````printf("Minimum time required is %d minutes.\n",minimum_time);
``````
And Here I am giving a tricky Test case:
Input:

Code: Select all

``````Set#1
3 3
1 1 1 2 1 3 3 1
2 3``````
AC Output:

Code: Select all

``````Set#1
Minimum time required is 7 minutes.``````