## 10426 - Knights' Nightmare

Moderator: Board moderators

Revenger
Experienced poster
Posts: 132
Joined: Sun Apr 14, 2002 12:27 pm
Location: Russia

### 10426 - Knights' Nightmare

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][x+dx,y+dy]<=p then exit;
inf[id][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][x+dx,y+dy]<=p then exit;
inf[id][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], sizeof(inf[id]), 255);
inf[id][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] := inf[id];
order[1,1] := Mr;
order[1,2] := Mc;
b := 1; bc := 1;
e := 2; ec := 0;
p := inf[id][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[x,y]=255 then begin getit:=-1; exit; end else
r:=r+inf[x,y];
end;
if inf[id][x,y]=255 then begin getit:=-1; exit; end;
r:=r+inf[id][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]

Revenger
Experienced poster
Posts: 132
Joined: Sun Apr 14, 2002 12:27 pm
Location: Russia

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

Thanks to all who tries to help me I get it. I get Accepted Larry
Guru
Posts: 647
Joined: Wed Jun 26, 2002 10:12 pm
Location: Hong Kong and New York City
Contact:
I can't get pass the monster part. Can someone give me a hint on how to handle the monster? Andrey Mokhov
Experienced poster
Posts: 128
Joined: Fri Nov 15, 2002 7:45 am
Location: Kyrgyzstan
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.

Larry
Guru
Posts: 647
Joined: Wed Jun 26, 2002 10:12 pm
Location: Hong Kong and New York City
Contact:
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!

magicalan
New poster
Posts: 3
Joined: Wed Jan 29, 2003 1:52 pm
Location: Hong Kong 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.

epsilon0
Experienced poster
Posts: 112
Joined: Tue Nov 12, 2002 11:15 pm
Location: Paris, France.

### 10426

(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[MAXSIZE * MAXSIZE], newland[MAXSIZE * MAXSIZE];

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

square kings, 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 = { 1, -1, 2, -2, 1, -1, 2, -2};
const char moves_j = { 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;
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;
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 = knightland;
land = knightland;
land = knightland;
land = knightland;
land[k] = knightland[k];
for(i=0; i< land_Nrow * land_Ncol; i++)
{
jmps = land + land + land[i] + land[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]
Last edited by epsilon0 on Tue Mar 18, 2003 5:13 pm, edited 1 time in total.
We never perform a computation ourselves, we just hitch a ride on the great Computation that is going on already. --Tomasso Toffoli

epsilon0
Experienced poster
Posts: 112
Joined: Tue Nov 12, 2002 11:15 pm
Location: Paris, France.

### nevermind

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
We never perform a computation ourselves, we just hitch a ride on the great Computation that is going on already. --Tomasso Toffoli

bery olivier
Learning poster
Posts: 90
Joined: Sat Feb 15, 2003 1:39 am
Location: Paris, France
Contact:

### ID !!

You shouldn't give your ID on this forum. A+.
Olivier.
Not AC yet AC at last Cletus
New poster
Posts: 11
Joined: Tue May 13, 2003 5:15 am
Location: Up a tree, hatless.

### 10426: something odd WA/PE

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?

``````

bery olivier
Learning poster
Posts: 90
Joined: Sat Feb 15, 2003 1:39 am
Location: Paris, France
Contact:

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

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]
Not AC yet AC at last Cletus
New poster
Posts: 11
Joined: Tue May 13, 2003 5:15 am
Location: Up a tree, hatless.

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

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?

``````

UFP2161
A great helper
Posts: 277
Joined: Mon Jul 21, 2003 7:49 pm
Contact:
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.

Articuno
Learning poster
Posts: 78
Joined: Sun Nov 30, 2008 5:00 pm

### Re: 10426 - Knights' Nightmare

Can anyone give me some critical test cases? I am getting WA.... Here is my code:

Code: Select all

``AC``
May be tomorrow is a better day............ mak(cse_DU)
Learning poster
Posts: 72
Joined: Tue May 30, 2006 5:57 pm

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

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.``````
Mak
Help me PLZ!!