Not so off-topic: URI is University Regional Igraduate, a university of Erechim, RS. Online Judge is a competitive programming platform, or something.
This problem is iterative: are N
test cases and each case has a certain number of shots of such a weapon. And for each shot the reaction will be J
or S
, jump or still stand. 2 lines bring the height pairs of the shot / player attitude, and the output for each series is the number of times the guy was hit.
The decision is a table: the height of the shot goes from 1 to 7. In case he stands still the height is 1 or 2, he will be hit. And if he jumps and the height is 3 or higher, he will also be hit. Nothing else. Here is the table:
Alt < 3 Pula? Resultado
N N A Salvo
N S Atingido
S N Atingido
S S A Salvo
In the example, this table in C has the 4 results
int destino[2][2] = {0, 1, 1, 0}; // os resultados
Example in C
Of course already having the 4 cases of the example it would be better to be able to test with these and read from a file, and only if it worked would read from the standard entry, as the case of the program in the such Online Judge.
Reading data from the keyboard is much more boring and complicated than reading from a simple file that you type into the IDE itself, and I’ll show in the example that you can use the same code...
Here is the sample input data
4 repeticoes
9 pulos
1 3 2 3 3 1 2 2 1
JJSSSJSSJ
49 pulos
1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 6 7 7 7 7 7 7 7
SSSSSSSSSSSSSSJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
4 pulos
1 2 2 1
SJJS
1 pulo
1
J
Depending on how you read in C you can even leave text in the file so you don’t have to look for the tests in the middle of the file...
And the expected result
4
49
2
0
So the simplest thing is to put this data into a file, like
exemplo.txt
And the program in C accepts an optional parameter which is the obvious file name. So you can test with data from a file you type in the editor itself, and if you do not use the parameter the program reads from the same keyboard...
Running the example
The 4 obvious tests: 2J 4J 2S 4S
remembering that with height less than 3 if jump is saved, and with height greater than 2 if jump is reached, and 0 indicates that was not reached...
SO>./f1-0903
1
1
2
J
0
SO>./f1-0903
1
1
4
J
1
SO> ./f1-0903
1
1
2
S
1
SO> ./f1-0903
1
1
4
S
0
Of course the output would be only the fourth line of each case, the number of hits.
0
1
1
0
calling with the file that has the sample data
SO> ./f1-0903 exemplo.txt
4
49
2
0
Of course f1-0903
was the name of the program on the test machine.
And that’s the expected result.
reading from file OR keyboard
FILE* ent;
if (argc > 1)
{ // veio algo entao e o nome do arquivo
ent = fopen(argv[1], "r");
if (ent == NULL) return -1;
}
else
ent = stdin; // nao veio o arquivo...
Just that. If nothing comes on the command line, read the keyboard data.
It doesn’t make sense to keep typing random data for each test.
In the example I used fgets()
to read the values that come alone in the line so as not to waste time with buffer bids, and to be able to write in the rest of the line so that you don’t have to count in the editor :)
After reading the total of tests the program has a loop to do the tests, and ends.
The test loop reads the total of shots and the height vector.
You don’t have to read the action vector because it’s useless. We just need to know the action because we already have the height of the shot, and then you can add right into the number of hits in a row according to the table that has above
mortes += destino[altura[t] < 3][mov == 'J'];
the whole program
/*
EXEMPLO C relativo a questao
/questions/526544
e ao problea 1250 do URI Online Judge
https://www.urionlinejudge.com.br/judge/pt/problems/view/1250
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char linha[200];
FILE* ent;
if (argc > 1)
{ // veio algo entao e o nome do arquivo
ent = fopen(argv[1], "r");
if (ent == NULL) return -1;
}
else
ent = stdin; // nao veio o arquivo...
int destino[2][2] = {0, 1, 1, 0}; // os resultados
fgets(linha, sizeof linha, ent);
int N = 0; // o total de testes
int res = sscanf(linha, "%d", &N);
if (res < 0) return -1;
// os N testes
for (int n = 0; n < N; n += 1)
{ // o teste 'n'
int T = 0; // disparos
fgets(linha, sizeof linha, ent);
res = sscanf(linha, "%d", &T);
if (res < 0) return -2;
// os 'T' disparos
int altura[50];
for (int t = 0; t < T; t += 1)
{
// le o vetor das alturas
res = fscanf(ent, "%d", altura + t);
if (res < 0) return -2;
}; // for(t)
fgets(linha, sizeof linha, ent); // le o '\n' da linha anterior
// calcula as mortes afinal
char mov; // movimento
int mortes = 0;
for (int t = 0; t < T; t += 1)
{ // para cada altura testa se foi atingido
res = fscanf(ent, "%c", &mov);
if (res < 0) return -2;
mortes += destino[altura[t] < 3][mov == 'J'];
}; // for(t)
printf("%d\n", mortes);
fgets(linha, sizeof linha, ent);
}; // for (n)
fclose(ent);
return 0;
}
about your program
int rep, mov, ace, i, i2;
scanf("%d", &rep);
for (i = 0; i < rep; i++)
{
ace = 0;
scanf("%d", &mov);
Avoid this type of construction. Even if it is a program for "competition" show the subject who is using the program what he expects to read. And it would not be too much to show what you have read. Many the program goes wrong because you think you have read something and have not read it, as if to confuse '0'
the letter and 0
the number.
Always test the return of scanf()
. As in this case only one specifier can return 1
, 0
or -1
. If you read the number you will return 1
, but if not read what is the point of following the program? Try typing a x
at that time...
In the for
always declare the loop control variable. This was a language problem, fixed about 40 years ago.
Avoid declaring more than one variable per line. Lines are free. And initialize all variables. It will save you many times.
Use more expressive names, especially in cases like i
and i2
which are global in main()
You cannot declare
int tiro[mov];
must be a known compile-time value such as
int tiro[300];
Or should allocate on time, as in
int* tiro = (int*) malloc(300 * sizeof (int))
example
Cropping and pasting from your program, compare with a common way of writing this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int rep = 0;
int mov = 0;
int ace = 0;
printf("rep? : ");
int res = scanf("%d", &rep);
if (res < 0 ) return - 1;
printf("rep = %d\n", rep);
for (int i = 0; i < rep; i++)
{
ace = 0;
printf("mov? : ");
res = scanf("%d", &mov);
if (res < 0) return -2;
if (mov > 512) mov = 512; // um limite...
printf("mov = %d\n", mov);
// le os tiro[0] a tiro[mov-1]
int* tiro = (int*)malloc(mov * sizeof(int));
for (int i2 = 0; i2 < mov; i2++)
{
res = scanf("%d", &tiro[i2]);
if (res < 0) return -3;
}
// mostra os caras...
printf("Tiro:\n");
for (int i2 = 0; i2 < mov; i2++)
{
printf("%d ", tiro[i2]);
if ((i2 % 4) == 3) printf("\n"); // 4 por linha
}
printf("\n");
free(tiro); // apaga o vetor
}
return 0;
}
that allocates the vector 'shot[]`to each repeat and erases at the end
exit
rep? : 1
rep = 1
mov? : 8
mov = 8
1
2
3
4
5
6
7
8
Tiro:
1 2 3 4
5 6 7 8
+1, but with caveat. It only makes sense, vc check error return, if the error needs to be dealt with and if you know how to do it. In the case of
scanf
and competitive programming, if for some reason your program does not read the input your solution will not pass the test and treatment you give withreturn -1;
does not add anything since the result will be WA 100% which would be the same if your solution were incorrect. Here, you have two alternatives, completely ignore the return ofscanf()
- what I would do - or treat by invokingabort()
and the URI reports that there has been a Runtime error.– Vander Santos
Yes and no, @Vandersantos. That’s because before you submit the program you need it ready and testing by error and showing what you read you’ll probably get to the point of submitting the result, and that’s the competition after all. Once you’re right, it takes minutes to get those tests off. To be ready without these tests can take much longer than it takes to get it out.
– arfneto
Sorry @arfneto, I am new here in the OS. I ended up making a mistake on the issue number, I corrected it now in the statement. In case, the problem I had is that on some occasions the value at position 0 of the shooting array was replaced and I didn’t know why this is happening
– Henrique Hahn
I understand. Even correcting the things I said about, does the corruption persist? I will see later if I find something
– arfneto
No, the corruption has been fixed. Can you just explain to me a little better how the shooting array works? I just started with C, so I’m pretty lost in some things yet
– Henrique Hahn
I saw such a problem. The only array it needs is from the heights of the shots, because the actions come together. I’ll leave an example that might help you understand
– arfneto