QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#71376#3417. GrachtenocAC ✓11ms1880kbC++145.0kb2023-01-09 21:14:442023-01-09 21:14:45

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-09 21:14:45]
  • 评测
  • 测评结果:AC
  • 用时:11ms
  • 内存:1880kb
  • [2023-01-09 21:14:44]
  • 提交

answer

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINE 1024
char line[MAXLINE];

/* Number of pre-calculated primes */
#define NUM_FIRST_PRIMES 4096
unsigned int curr_prime_ix = 0;
unsigned int first_primes[NUM_FIRST_PRIMES];

/* Simple prime number "sieve" */
int is_prime(unsigned int num)
{
   unsigned int limit;
   unsigned int i;
   unsigned int *p;

   if (num < 4) {
      return 1;
   }

   /* Quickly sort out even numbers */
   if ((num & 1) == 0) {
      return 0;
   }

   /* Only need to test up to square root of num */
   limit = num / 2 + 1;

   /* Try primes in first_primes[] first */
   for (i = 0, p = first_primes; ((*p) < limit) && (i < curr_prime_ix); i++, p++) {
      if ((num % (*p)) == 0) {
         /* Not a prime */
         return 0;
      }
   }

   i = first_primes[curr_prime_ix - 1];
   if (i > limit) {
      return 1;
   }

   /* Try numbers above first_primes */
   for (; i < limit; i += 2) {
      if ((num % i) == 0) {
         /* Not a prime */
         return 0;
      }
   }

   /* This must be a prime */
   return 1;
}

void init_primes(void)
{
   int i;

   first_primes[0] = 2;
   first_primes[1] = 3;
   first_primes[2] = 5;
   curr_prime_ix = 3;

   i = first_primes[curr_prime_ix - 1] + 2;

   /* Fill in first_primes */
   for (; curr_prime_ix < NUM_FIRST_PRIMES; i += 2) {
      if (is_prime(i)) {
         first_primes[curr_prime_ix++] = i;
      }
   }
}

/* Maximum number of prime factors in number */
#define MAX_P_FAC 512
typedef struct pfac {
   unsigned int factors[MAX_P_FAC];
   unsigned char factor_active[MAX_P_FAC];
   int num_factors;
} pfac_t;

void insert_factor(unsigned int prime, pfac_t *f)
{
   if (f->num_factors < MAX_P_FAC) {
      f->factors[f->num_factors] = prime;
      f->factor_active[f->num_factors] = 1;
      f->num_factors++;
   } else {
      fprintf(stderr, "prime factors array full :(\n");
   }
}

void prime_factorize(unsigned int num, pfac_t *f)
{
   unsigned int limit;
   unsigned int i;

   memset(f, 0, sizeof(pfac_t));

   /* Get next prime factor */
   do {
      limit = num / 2 + 2;
      for (i = 2; i < limit; i++) {
         if (is_prime(i)) {
            if ((num % i) == 0) {
               insert_factor(i, f);
               num /= i;
               break;
            }
         }
      }
   } while (i < limit);

   /* Insert remaining num, which must be the last prime */
   insert_factor(num, f);
}

void reduce_frac(pfac_t *n, pfac_t *d)
{
   int i, j;

   for (i = 0; i < n->num_factors; i++) {
      for (j = 0; j < d->num_factors; j++) {
         if (n->factor_active[i] && d->factor_active[j]) {
            if (n->factors[i] == d->factors[j]) {
               n->factor_active[i] = 0;
               d->factor_active[j] = 0;
               break;
            }
         }
      }
   }
}

unsigned int get_pfac_num(pfac_t *f)
{
   int i;
   unsigned int res = 1;
   for (i = 0; i < f->num_factors; i++) {
      if (f->factor_active[i]) {
         res *= f->factors[i];
      }
   }

   return res;
}

void print_reduced_fraction(unsigned int num, unsigned int den)
{
   pfac_t f_num, f_den;

   prime_factorize(num, &f_num);
   prime_factorize(den, &f_den);

   /* reduce numerator/denominator */
   reduce_frac(&f_num, &f_den);

   /* print reduced fraction */
   printf("%u/%u\n", get_pfac_num(&f_num), get_pfac_num(&f_den));
}

int main(int argc, char *argv[])
{
   FILE *fp;
   char *ret;

   /* Assign fp to either stdin or argv[1] */
   if (argc == 1) {
      /* No arguments = stdin */
      fp = stdin;
   } else {
      /* - also means stdin */
      if(!strcmp(argv[1], "-")) {
         fp = stdin;
      } else {
         /* Open argv[1] */
         fp = fopen(argv[1], "r");
         if (!fp) {
            perror(argv[1]);
            exit(EXIT_FAILURE);
         }
      }
   }

   init_primes();

   do {
      /* Read line from selected input */
      ret = fgets(line, MAXLINE - 1, fp);
      if (ret) {
         unsigned int ab, ac, bd;
         char *endp;
         char *startp = line;

         ab = strtoul(startp, &endp, 0);
         if (ab == 0 || startp == endp) {
            exit(EXIT_FAILURE);
         }
         startp = endp;
         ac = strtoul(startp, &endp, 0);
         if (ac == 0 || startp == endp) {
            exit(EXIT_FAILURE);
         }
         startp = endp;
         bd = strtoul(startp, &endp, 0);
         if (bd == 0) {
            exit(EXIT_FAILURE);
         }

         /* Do calculation and reduce fraction */
         if (bd > ac) {
            print_reduced_fraction(ab * ac, bd - ac);
         } else {
            fprintf(stderr, "Error: bd must be larger than ac\n");
         }
      }

   } while (ret);

   if (fp) {
      fclose(fp);
   }

   return EXIT_SUCCESS;
}


/**
 * Local Variables:
 * mode: c
 * indent-tabs-mode: nil
 * c-basic-offset: 3
 * End:
 */

详细

Test #1:

score: 100
Accepted
time: 11ms
memory: 1748kb

input:

143 715 923
143 715 924
143 715 925
143 715 926
143 715 927
143 715 928
143 715 929
143 715 930

output:

7865/16
9295/19
20449/42
102245/211
102245/212
102245/213
102245/214
20449/43

result:

ok 8 lines

Test #2:

score: 0
Accepted
time: 7ms
memory: 1516kb

input:

997 997 998
997 998 999
997 999 1000
998 997 998
998 998 999
998 999 1000
999 997 998
999 998 999
999 999 1000
1000 997 998
1000 998 999
1000 999 1000

output:

994009/1
995006/1
996003/1
995006/1
996004/1
997002/1
996003/1
997002/1
998001/1
997000/1
998000/1
999000/1

result:

ok 12 lines

Test #3:

score: 0
Accepted
time: 7ms
memory: 1880kb

input:

670 226 928
930 513 956
708 537 893
773 708 995
984 88 1000
871 771 890
115 93 666
532 516 615
436 797 992
983 400 998
337 442 941
798 60 818
804 255 911
926 606 994
110 488 782
808 702 967
140 70 853
647 467 885
990 245 993
757 844 986
847 489 911
106 149 670
960 341 971
668 440 989
847 874 1000
66...

output:

75710/351
477090/443
95049/89
547284/287
1804/19
671541/119
3565/191
91504/33
347492/195
196600/299
148954/499
23940/379
51255/164
140289/97
26840/147
567216/265
9800/783
302149/418
11025/34
319454/71
414183/422
15794/521
10912/21
293920/549
52877/9
22113/25
3972/101
131537/187
627324/17
157537/128
...

result:

ok 109 lines

Test #4:

score: 0
Accepted
time: 11ms
memory: 1476kb

input:

5 3 7
5 3 8
1 2 3
23 42 47
500 500 1000
1 1 1000

output:

15/4
3/1
2/1
966/5
500/1
1/999

result:

ok 6 lines

Test #5:

score: 0
Accepted
time: 11ms
memory: 1752kb

input:

1 1 2
1 2 3
2 1 2
2 2 3

output:

1/1
2/1
2/1
4/1

result:

ok 4 lines