[editorial] SRM 392 Div 2

  • Toivoa
    Toivoa

    SRM 392 에디토리얼 쓰는 김에 div2의 editorial도 활성화되길 바라는 마음에서 div2까지 씁니다.
    Easy (250 pts.)

    • 문제 설명 2007년 1월 1일에 만들어진 캔디들이 있습니다. 이 캔디를 매 월말에 먹었을 때 캔디의 평균적인 수명을 구해야 합니다. [spoiler="더 보기..."]
    • 문제 해법 그냥 계산하시면 됩니다. 저는 floating point error를 피하기 위해서 int로 계산했습니다. ~~~ cpp

    double getAverage(vector eatenCandies)
    {
    int i;
    int d = 0;
    int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int tot = 0, candies = 0;
    for (i = 0; i < 12; i++)
    {
    d += dates[i];
    tot += eatenCandies[i] * d;
    candies += eatenCandies[i];
    }
    return double(tot) / double(candies);
    }

    [/spoiler]
    
    
    Medium (500 pts.)
    
    
    * div1의 easy와 같은 문제입니다. div1의 editorial을 참조하세요.
    
    
    Hard (1000 pts.) 
    
    * 문제 설명
    n by n의 table을 [0, d)의 숫자들로 채우려 합니다. 한 row나 column에는 반드시 한 숫자가 최소한 한번 나와야 합니다.
    이를 만족하는 table들 중 "사전순으로 가장 작은" 것을 찾아야 합니다.
    [spoiler="더 보기..."]
    * 문제 해법
    예제를 보시면 알겠지만 가장 위와 왼쪽 줄은 (0 .. 0) 1 2 3 ... d 와 같은 식으로 채우는 것이 가장 좋습니다.
    그 후에 나머지 오른쪽 아래 공간은 모든 숫자가 한 번씩만 사용될 수 있다는 것을 이용해서 백트래킹으로 구할 수 있습니다.
    ~~~ cpp
    
    int table[50][50];
    int usex[50][50];
    int usey[50][50];
    class QuasiLatinSquares
    {
    public:
    int N, D;
    bool solve(int x, int y)
    {
     if (y == N) return solve(x + 1, 0);
     if (x == N) return true;
     if (table[x][y] != -1) return solve(x, y + 1);
     for (int l = 0; l < D; l++)
     {
      if (usex[x][l] == 0 && usey[y][l] == 0)
      {
       usex[x][l] = usey[y][l] = 1;
       table[x][y] = l;
       if (solve(x, y + 1)) return true;
       table[x][y] = -1;
       usex[x][l] = usey[y][l] = 0;
      }
     }
     return false;
    }
    vector<string> makeSquare(int n, int d)
    {
     N = n; D = d;
     vector<string> ret;
     int i, j, k = n - d + 1;
     fill(table[0], table[n], -1);
     for (i = 0; i < k; i++)
     {
      for (j = 0; j < k; j++)
       table[i][j] = 0;
      for (j = k; j < n; j++)
      {
       table[i][j] = table[j][i] = j - k + 1;
       usex[j][j - k + 1] = usey[j][j - k + 1] = 1;
      }
     }
     solve(0, 0);
     for (i = 0; i < n; i++)
     {
      char cc[100];
      char *s = cc;
      for (j = 0; j < n; j++)
      {
       sprintf(s, "%d ", table[i][j]);
       while (*s != 0) s++;
      }
      s--;
      *s = 0;
      ret.push_back(cc);
     }
     return ret;
    }
    };

    [/spoiler]

    [이 글은 과거 홈페이지에서 이전된 글입니다. 원문보기]

    16년 전
0개의 댓글이 있습니다.
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.