Change in Array Value

Asked

Viewed 54 times

-2

I started learning about C, and asking some questions of URI I found a mistake I don’t know how to fix. When entering the values inside the shot array, it inserts all the values correctly, but when going through the scan of the jump array, shot[0] gets 0. Someone knows why and how to fix it?

  • The first line of the input contains an integer N indicating the number of test cases. Each test case consists of 3 lines.
  • The first line contains an integer T (1 T 50) indicating the number of shots.
  • The second line contains whole T, which represent the sequence of the heights at which the shots are being fired. Each element of the sequence shall be between 1 and 7 inclusive.
  • The third line of the input contains the string "jumps", which represents the sequence of jumps that Kiloman will attempt; 'J' means he will jump and’S' means he will stand still
  • 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
  • In the end it is necessary to present the number of times he is reached

Test cases I’m using, the first returns 25 (the right is 26) and the second returns 6 (the right is 5)

1 48 6 5 4 4 2 7 1 4 5 1 6 5 6 5 5 4 1 1 2 7 5 6 7 5 5 3 4 7 2 5 6 6 5 3 7 4 1 4 1 2 2 7 3 1 7 7 7 2 JJJSJJSSJSSSJJJSJSSSSJSSJSSJSSJJSJJSSSJJJSJSJJJJ

1 16 4 4 3 3 4 4 5 4 5 6 1 3 5 7 2 3 SSSSJSSSSJJJJSJJ

#include <stdio.h>

int main() {
    int rep, mov, ace, i, i2;
    scanf("%d", &rep);
    for(i = 0; i < rep; i++){
        ace = 0;
        scanf("%d", &mov);

        int tiro[mov];
        for(i2 = 0; i2 < mov; i2++){
            scanf("%d", &tiro[i2]);
        }
        printf("%d\n", tiro[0]); //Valor de tiro continua sendo o mesmo

        char pulo[mov];
        scanf("%s", &pulo);

        printf("%d\n", tiro[0]); //Valor de tiro já virou 0
        for(i2 = 0; i2 < mov; i2++){
            if((tiro[i2] <= 2 && pulo[i2] == 'S') || (tiro[i2] >= 3 && pulo[i2] == 'J')){
                ace++;
            }
            printf("O teste %d, com os valores %d/%c teve %d acerto(s)\n", i2+1, tiro[i2], pulo[i2], ace);
        }
        printf("%d\n", ace);
    }
    return 0;
}

1 answer

2


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 with return -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 of scanf() - what I would do - or treat by invoking abort() and the URI reports that there has been a Runtime error.

  • 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.

  • 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

  • I understand. Even correcting the things I said about, does the corruption persist? I will see later if I find something

  • 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

  • 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

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.