10426 - Knights' Nightmare

All about problems in Volume 104. If there is a thread about your problem, please use it. If not, create one with its number in the subject.

Moderator: Board moderators

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

10426 - Knights' Nightmare

Post by Revenger » 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
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]

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

Yes! I fix it!!!!!

Post by Revenger » Mon Jan 13, 2003 8:49 pm

Thanks to all who tries to help me :D
I get it. I get Accepted 8)

Larry
Guru
Posts: 647
Joined: Wed Jun 26, 2002 10:12 pm
Location: Hong Kong and New York City
Contact:

Post by Larry » 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?

:-?

Andrey Mokhov
Experienced poster
Posts: 128
Joined: Fri Nov 15, 2002 7:45 am
Location: Kyrgyzstan

Post by Andrey Mokhov » 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.

Larry
Guru
Posts: 647
Joined: Wed Jun 26, 2002 10:12 pm
Location: Hong Kong and New York City
Contact:

Post by Larry » Sat Jan 18, 2003 6:18 am

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!

magicalan
New poster
Posts: 3
Joined: Wed Jan 29, 2003 1:52 pm
Location: Hong Kong

Post by magicalan » Thu Jan 30, 2003 6:04 am

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.

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

10426

Post by epsilon0 » Mon Mar 17, 2003 6:50 pm

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]
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

Post by epsilon0 » 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
instead of
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 !!

Post by bery olivier » Mon Mar 17, 2003 7:30 pm

You shouldn't give your ID on this forum.

:wink:
A+.
Olivier.
Not AC yet Image AC at last Image

Cletus
New poster
Posts: 11
Joined: Tue May 13, 2003 5:15 am
Location: Up a tree, hatless.

10426: something odd WA/PE

Post by Cletus » 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
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?



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

Re: 10426: something odd WA/PE

Post by bery olivier » 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]
Not AC yet Image AC at last Image

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.

Post by Cletus » 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 
"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? 


User avatar
UFP2161
A great helper
Posts: 277
Joined: Mon Jul 21, 2003 7:49 pm
Contact:

Post by UFP2161 » 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.

Articuno
Learning poster
Posts: 78
Joined: Sun Nov 30, 2008 5:00 pm
Location: IUT-OIC, Dhaka, Bangladesh

Re: 10426 - Knights' Nightmare

Post by Articuno » 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
May be tomorrow is a better day............ :)

mak(cse_DU)
Learning poster
Posts: 72
Joined: Tue May 30, 2006 5:57 pm
Location: bangladesh

Re: 10426: something odd WA/PE

Post by mak(cse_DU) » 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.
Mak
Help me PLZ!!

Post Reply

Return to “Volume 104 (10400-10499)”