Page 1 of 2

10426 - Knights' Nightmare

Posted: Mon Jan 13, 2003 8:33 pm
by Revenger
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
Readln(S);
test:=test+1;
Writeln('Set#',test);
Readln(R,C);
for i := 1 to 4 do for j := 1 to 2 do Read(K[i,j]);
Readln;
Readln(Mr,Mc);
for i := 1 to 4 do FillK(i);
getans;
end;
end.[/pascal]

Yes! I fix it!!!!!

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

Posted: Thu Jan 16, 2003 11:36 am
by Larry
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
by Andrey Mokhov
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
by Larry
Thanks anyhow! :D

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
by magicalan
8)
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
by epsilon0
please help me i don't know why this is wrong:

(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 MONSTERSSQUARE (n_jmp)(~0 - 1)
#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++)
if (land[0] < MONSTERSSQUARE
&& land[1] < MONSTERSSQUARE
&& land[2] < MONSTERSSQUARE
&& land[3] < MONSTERSSQUARE)
{
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
by epsilon0
nevermind

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

ID !!

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

:wink:
A+.
Olivier.

10426: something odd WA/PE

Posted: Tue May 13, 2003 5:18 am
by Cletus

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
text around the answer.

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
cause "wrong answer"

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
by bery olivier
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
by Cletus

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 
"set#" instead of "Set#".

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
by UFP2161
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
by Articuno
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
by mak(cse_DU)
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.