Coding
  • Welcome
  • Baisc Knowledge
    • Vim
    • C
      • Library
    • Java
      • Setup
      • Java Basic
  • Kattis
    • Easy
      • A Second Opinion
      • A Shortcut to What?
      • A Stack of Gold
      • ACM Contest Scoring
      • ASCII kassi
      • Aaah!
      • Add Two Numbers
      • Adding Trouble
      • Afjörmun
      • Airfare Grants
      • Above Average
      • Akcija
      • Alphabet Spam
      • Amerískur vinnustaður
      • Anti-Palindrome
      • Apaxiaaaaaaaaaaaans!
      • Arithmetic Functions
      • Arm Coordination
      • Arrangement
      • Attendance
      • Autori
      • Average Character
      • Avion
      • Baby Bites
      • Babylonian Numbers
      • ABC
      • Aldur
      • Backspace
      • Bannorð
      • Barcelona
      • Basketball One-on-One
      • Batter Up
      • Beavergnaw
      • Bela
      • BergMál
      • Bergur*
      • Akureyri*
      • Best Compromise
      • Best Relay Team*
      • Besta gjöfin
      • Betting
      • Bijele
      • Bilað Lyklaborð
      • Bitte ein Bit
      • Blandað Best
      • Blaðra
      • Blaðra2
      • Bluetooth*
      • Booking a Room
      • Bottle Opening
      • Bounding Robots
      • Breaking Branches*
      • Bracket Matching*
      • Broken Swords
      • Building Pyramids
      • Bus
      • Bus Assignment
      • CPR Number
      • Call for Problems
      • Canadians, eh?
      • Candy Store
      • Cetiri
      • Cetvrta
      • Champernowne Verification
      • Chanukah Challenge
      • Chardonnay
      • Chocolate Division*
      • Chugging
      • Cinema Crowds 2
      • Class Field Trip
      • ASCII Kassi 2
      • Coffee Cup Combo
      • Cold-puter Science
      • Composed Rhythms
      • Cookies
      • Cooking Water
      • Cornhusker
      • Cosmic Path Optimization
      • Count the Vowels
Powered by GitBook
On this page
  • Question
  • Solution
  • Idea
  • Code
Edit on GitHub
  1. Kattis
  2. Easy

Beavergnaw

PreviousBatter UpNextBela

Last updated 6 months ago

Question

Solution

Idea

This is purely a math problem, a math problem about the solid geometry. Quite boring since it took me a while to derive the math formula. The steps are summarised as follows:

  1. Calculate the volumne of the bigger cylinder total, which is π∗(D2)2∗D\pi*(\frac{D}{2})^2*Dπ∗(2D​)2∗D

  2. Use total minus the input V to get the volume of the wood eaten by the beaver, wood=total−v\text{wood}=\text{total}-\text{v}wood=total−v

Now the trickiest thing begins, we need to deduct the two truncated cone. Here we use the bigCone−smallCone\text{bigCone}-\text{smallCone}bigCone−smallCone to calculate. And we first consider the upper half.

Notice that for the upper half, the bigCone\text{bigCone}bigCone is with both radius and height as D2\frac{D}{2}2D​, while the smallCone\text{smallCone}smallCone is with both radius and height as d2\frac{d}{2}2d​. So, the volume for the upper truncated cone should be 13(π(D2)3−π(d2)3)\frac{1}{3}(\pi(\frac{D}{2})^3-\pi(\frac{d}{2})^3)31​(π(2D​)3−π(2d​)3).

So, for the two truncated cones, their total volume should be 23(π(D2)3−π(d2)3)\frac{2}{3}(\pi(\frac{D}{2})^3-\pi(\frac{d}{2})^3)32​(π(2D​)3−π(2d​)3), which is same as 13(π(D2)2⋅D−π(d2)2⋅d)\frac{1}{3}(\pi(\frac{D}{2})^2\cdot D-\pi(\frac{d}{2})^2\cdot d)31​(π(2D​)2⋅D−π(2d​)2⋅d).

Notice that the volumne of two truncated cones plus the volume of the inner cylinder will be the volumne of wood\text{wood}wood. And the volumne of the cylinder is given by π(d2)2⋅d\pi(\frac{d}{2})^2\cdot dπ(2d​)2⋅d, which can be simplify to 2πr3,where r=d22\pi r^3,\text{where }r=\frac{d}{2}2πr3,where r=2d​. (Now, you should be able to solve for the ddd). Manipulate the formula, we have 23(2πr3)=wood−13π(D22)⋅D\frac{2}{3}(2\pi r^3)=\text{wood}-\frac{1}{3}\pi(\frac{D}{2}^2)\cdot D32​(2πr3)=wood−31​π(2D​2)⋅D

  1. Now, let's define a new variable bigCones, whose value is 13π(D2)2⋅D\frac{1}{3}\pi(\frac{D}{2})^2\cdot D31​π(2D​)2⋅D

  2. Then, define another intermediate variable shape, whose value is wood−bigCones\text{wood}-\text{bigCones}wood−bigCones

  3. Last and finally, define the last variable cylinder to represent the volume of the inner cylinder, whose value is shape⋅32\text{shape}\cdot \frac{3}{2}shape⋅23​.

  4. Now, our d=2⋅r=2⋅cylinder2π3d=2\cdot r=2\cdot\sqrt[3]{\frac{\text{cylinder}}{2\pi}}d=2⋅r=2⋅32πcylinder​​

Code

https://open.kattis.com/problems/beavergnawopen.kattis.com
https://github.com/mendax1234/Coding-Problems/blob/main/kattis/beavergnaw/beavergnaw.c
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define BUF_SIZE 32
static
int skip_space() {
  int c;
  do {
    c = fgetc(stdin);
  } while (isspace(c) && c != EOF);
  return c;
}

static
size_t fill_buffer(char *buf, size_t len) {
  int c;
  size_t i = 0;
  while (1) {
    c = fgetc(stdin);
    if (c == EOF || isspace(c)) {
      buf[i] = 0;
      return i + 1;
    }
    buf[i] = (char)c;
    i = i + 1;

    if (i == len) {
      return i;
    }
  }
}

/**
 * @brief Read and return a string from standard input (until
 * we reach a spa
 *
 * @return The string read if successful.  The caller is
 * responsible for freeing the memory allocated to the string.
 * Return NULL if an error is encountered when reading.
 *
 * @note Based on FIO20-C. Avoid unintentional truncation when
 * using fgets() or fgetws()
 * https://wiki.sei.cmu.edu/
 */
char* cs1010_read_word()
{
  char buf[BUF_SIZE];
  char *ret = malloc(1);
  if (ret == NULL) {
    return NULL;
  }
  size_t total_len = 1;
  size_t len;

  int c = skip_space();
  if (c == EOF) {
    free(ret);
    printf("EOF encountered.  return NULL\n");
    return NULL;
  }
  *ret = (char)c;

  do {
    len = fill_buffer(buf, BUF_SIZE);
    char *temp = realloc(ret, total_len + len + 1);
    if (temp == NULL) {
      free(ret);
      return NULL;
    }
    ret = temp;
    memcpy(ret + total_len, buf, len); // concat the string
    total_len += len;
  } while (len == BUF_SIZE && buf[len-1] != 0);
  return ret;
}

/**
 * @brief Read and return a long int from standard input.
 *
 * @details Based on INT05-C from SEI CERT C Coding Standard
 * https://wiki.sei.cmu.edu/
 *
 * @return the value read if successful.  Return LONG_MAX
 * with an error message printed if an error occured.
 */

long cs1010_read_long()
{
  char *buff;
  char *end_ptr;
  long number;

  buff = cs1010_read_word();
  if (buff == NULL) {
    fprintf(stderr, "cs1010_read_long: EOF or read error\n");
    return LONG_MAX;
  }
  errno = 0;

  number = strtol(buff, &end_ptr, 10);

  if (ERANGE == errno) {
    fprintf(stderr, "cs1010_read_long: number '%s' out of range\n", buff);
    free(buff);
    return LONG_MAX;
  }
  if (end_ptr == buff) {
    fprintf(stderr, "cs1010_read_long: '%s' is not a valid numeric input\n", buff);
    free(buff);
    return LONG_MAX;
  }
  if ('\n' != *end_ptr && '\0' != *end_ptr) {
    fprintf(stderr, "cs1010_read_long: reach the end without null/newline. '%s' remains\n", end_ptr);
    free(buff);
    return LONG_MAX;
  }
  free(buff);
  return number;
}

/**
 * @brief Read and return a string from standard input (until
 * we reach the new line.)
 *
 * @return the string read if successful.  The caller is
 * responsible for freeing the memory allocated to the string.
 * Return NULL if an error is encountered when reading.
 *
 * @note See FIO20-C. Avoid unintentional truncation when using fgets() or fgetws()
 * https://wiki.sei.cmu.edu/
 */
char* cs1010_read_line()
{
  char* buf = NULL;
  size_t dummy = 0;
  if (getline(&buf, &dummy, stdin) == -1) {
    fprintf(stderr, "cs1010_read_line: unable to read line into buffer\n");
    return NULL;
  }
  return buf;
}

/**
 * @brief Read and return a double from standard input.
 *
 * @return the value read if successful.  Return DOUBLE_MAX
 * with an error message printed if an error occured.
 */
double cs1010_read_double()
{
  char *buff;
  char *end_ptr;
  double number;

  buff = cs1010_read_word();
  if (buff == NULL) {
    fprintf(stderr, "cs1010_read_double: EOF or read error\n");
    return DBL_MAX;
  }
  errno = 0;

  number = strtod(buff, &end_ptr);

  if (ERANGE == errno) {
    free(buff);
    fprintf(stderr, "cs1010_read_double: number '%s' out of range\n", buff);
    return DBL_MAX;
  }
  if (end_ptr == buff) {
    free(buff);
    fprintf(stderr, "cs1010_read_double: '%s' is not a valid numeric input\n", buff);
    return DBL_MAX;
  }
  if ('\n' != *end_ptr && '\0' != *end_ptr) {
    free(buff);
    fprintf(stderr, "cs1010_read_double: reach the end without null/newline. '%s' remains\n", buff);
    return DBL_MAX;
  }
  free(buff);
  return number;
}

/**
 * @brief Read and return multiple long int from standard
 * input into an array.
 *
 * @return The array read if successful.  The caller is responsible
 * for freeing the array.  Return NULL if an error occured.
 */

long* cs1010_read_long_array(size_t how_many)
{
  long *buffer = calloc(how_many, sizeof(long));
  if (buffer == NULL) {
    return NULL;
  }

  for (size_t i = 0; i < how_many; i = i + 1) {
    buffer[i] = cs1010_read_long();
  }

  return buffer;
}

/**
 * @brief Read and return multiple double from standard
 * input into an array.
 *
 * @return The array read if successful.  The caller is responsible
 * for freeing the array.  Return NULL if an error occured.
 */
double* cs1010_read_double_array(size_t how_many)
{
  double *buffer = calloc(how_many, sizeof(double));
  if (buffer == NULL) {
    return NULL;
  }

  for (size_t i = 0; i < how_many; i = i + 1) {
    buffer[i] = cs1010_read_double();
  }

  return buffer;
}

/**
 * @brief Read and return multiple lines from standard
 * input into an array.
 *
 * @return The array read if successful.  The caller is responsible
 * for freeing the array and each string in the array.  Return NULL
 * if an error occured.
 */
char** cs1010_read_line_array(size_t how_many)
{
  char **buffer = calloc(how_many, sizeof(char*));
  if (buffer == NULL) {
    return NULL;
  }

  for (size_t i = 0; i < how_many; i = i + 1) {
    buffer[i] = cs1010_read_line();
    if (buffer[i] == NULL) {
      for (size_t j = 0; j < i; j = j + 1) {
        free(buffer[j]);
      }
      free(buffer);
      return NULL;
    }
  }

  return buffer;
}

/**
 * @brief Read and return multiple space-delimited words
 * from standard input into an array.
 *
 * @return The array read if successful.  The caller is
 * responsible for freeing the array and each string in
 * the array.  Return NULL if an error occured.
 */
char** cs1010_read_word_array(size_t how_many)
{
  char **buffer = calloc(how_many, sizeof(char*));
  if (buffer == NULL) {
    return NULL;
  }

  for (size_t i = 0; i < how_many; i = i + 1) {
    buffer[i] = cs1010_read_word();
    if (buffer[i] == NULL) {
      for (size_t j = 0; j < i; j = j + 1) {
        free(buffer[j]);
      }
      free(buffer);
      return NULL;
    }
  }

  return buffer;
}

/**
 * @brief Read a size_t value from the standard input.  
 * Reporting an error and return 0 instead of the value 
 * is less than 0..
 */
size_t cs1010_read_size_t() {
  char *buff;
  char *end_ptr;
  unsigned long number;

  buff = cs1010_read_word();
  if (buff == NULL) {
    fprintf(stderr, "cs1010_read_size_t: EOF or read error\n");
    return SIZE_MAX;
  }
  errno = 0;

  number = strtoul(buff, &end_ptr, 10);

  if (ERANGE == errno) {
    fprintf(stderr, "cs1010_read_size_t: number '%s' out of range of unsigned long\n", buff);
    free(buff);
    return SIZE_MAX;
  }
  if (end_ptr == buff) {
    fprintf(stderr, "cs1010_read_size_t: '%s' is not a valid numeric input\n", buff);
    free(buff);
    return SIZE_MAX;
  }
  if ('\n' != *end_ptr && '\0' != *end_ptr) {
    fprintf(stderr, "cs1010_read_size_t: reach the end without null/newline. '%s' remains\n", end_ptr);
    free(buff);
    return SIZE_MAX;
  }
  if (number > SIZE_MAX) {
    fprintf(stderr, "cs1010_read_size_t: number '%s' out of range of size_t\n", buff);
    free(buff);
    return SIZE_MAX;
  }
  free(buff);
  return number;
}
  
/**
 * @brief Print a double to standard output with format %.4f.
 */
void cs1010_print_double(double d)
{
  printf("%.4f", d);
}

/**
 * @brief Print a long to standard output with format %.4f.
 */
void cs1010_print_long(long d)
{
  printf("%ld", d);
}

/**
 * @brief Print a double to standard output with format %.4f,
 * followed by a newline.
 */
void cs1010_println_double(double d)
{
  cs1010_print_double(d);
  printf("\n");
}

/**
 * @brief Print a long to standard output with format %.4f, followed by a newline.
 */
void cs1010_println_long(long d)
{
  cs1010_print_long(d);
  printf("\n");
}

/**
 * @brief Print a string to standard output.
 */
void cs1010_print_string(char *s)
{
  printf("%s", s);
}

/**
 * @brief Print a string to standard output, followed by a newline.
 */
void cs1010_println_string(char *s)
{
  printf("%s\n", s);
}

/**
 * @brief Print a pointer to standard output.
 */
void cs1010_print_pointer(void *ptr)
{
  cs1010_print_long((long)ptr);
}

/**
 * @brief Print a pointer to standard output, followed by a newline.
 */
void cs1010_println_pointer(void *ptr)
{
  cs1010_println_long((long)ptr);
}

/**
 * @brief Print a size_t to standard output with format %zu.
 */
void cs1010_print_size_t(size_t d)
{
  printf("%zu", d);
}

/**
 * @brief Print a size_t to standard output with format %zu.
 */
void cs1010_println_size_t(size_t d)
{
  printf("%zu\n", d);
}

/**
 * @brief Print a bool to standard output with format %zu.
 */
void cs1010_print_bool(bool b)
{
  if (b) {
    printf("true");
  } else {
    printf("false");
  }
}

/**
 * @brief Print a bool to standard output with format %zu.
 */
void cs1010_println_bool(bool b)
{
  if (b) {
    printf("true\n");
  } else {
    printf("false\n");
  }
}

/**
 * @brief Clear the screen.
 */
void cs1010_clear_screen()
{
  printf("[2J[;H");
}

#define MAX_LEN 1000000

int main()
{
  double radius[MAX_LEN] = { 0.0 };
  long d = cs1010_read_long();
  long v = cs1010_read_long();
  long i = 0;
  while (d != 0 && v != 0)
  {
    double total = M_PI * pow((double)d / 2.0, 2.0) * (double)d;
    double wood = total - v;
    double bigCones = M_PI * pow((double)d / 2.0, 2.0) * (double)d / 3.0;
    double shape = wood - bigCones;
    double cylinder = shape * 1.5;
    double r = pow((cylinder / (2.0 * M_PI)), (1.0 / 3.0));
    radius[i] = 2 * r;
    i += 1;
    d = cs1010_read_long();
    v = cs1010_read_long();
  }
  for (long j = 0; radius[j] != 0; j += 1)
  {
    printf("%lf\n", radius[j]);
  }
}