본문 바로가기
Computer Science

Table Calculator

by OKOK 2019. 3. 15.


제한 조건

실행시간 : 최대 50개의 테스트 케이스를 합쳐서 10초 이내

 

메 모 리 : Heap, Global, Stack 등을 모두 합해 최대 512MB까지 사용 가능 (, 스택은 최대 1MB까지 사용 가능)

제출 횟수 제한

20

채점

답안을 제출하면 제공된 sample_input.txt 에 대한 결과를 판정해서 실시간으로 알려주며 그 의미는 다음과 같다.

 

Accept : sample input에 대하여 정답 또는 부분 점수 획득

 

Fail : sample input에 대하여 오답 또는 런타임 에러, time out

 

(※ sample_input.txt 파일 다운로드는 문제 지문 바로 아래에 있습니다)

 

최종결과는 별도의 채점용 input으로 진행되므로 시험 중 판정 결과와 다를 수 있다.

평가

최종 점수는 별도로 제작된 평가용 테스트 케이스로 측정하며, 동점자간에는 실행시간에 따라 점수 차이가 발생할 수 있습니다.

 

따라서 시험이 끝날 때까지 본인의 코드를 최적화 하시기를 권장합니다.



[코드 작성 시 주의점]

① C 또는 C++로 답안을 작성하시는 응시자께서는 검정시스템에 제출 시, Language에서 C++ 선택하신 후 제출해 주시기를 바랍니다.

② Main 부분과 User Code 부분으로 구성되어 있습니다.

A. Main 부분 : 수정할 수 없는 코드이며, 채점 시 주어지는 코드 그대로 사용됩니다.

B. User Code 부분 : 실제 응시자가 작성해야 하는 코드이며, 제출 시에는 코드 내에 라이브러리 함수뿐 아니라 표준 입출력 함수도 포함되어서는 안됩니다.

C. 서버에서는 Main 부분과 User Code 부분은 별도의 파일로 분리되어 컴파일이 됩니다. 

(main.cpp /solution.cpp 또는 Solution.java/UserSolution.java)


③ Local PC에서 프로그래밍할 시 유의 사항

A. 2개의 파일을 생성하셔야 합니다.  (main.cpp/solution.cpp 또는 Solution.java/UserSolution.java)

B. Main 부분의 코드를 main.cpp 또는 Solution.java에 복사해서 사용하시기 바랍니다.

C. sample_input.txt를 사용하시기 위해서는 Main 부분의 코드 내에 표준 입력을 파일로 전환하는 코드(주석처리 되어 있음)의 주석을 풀어서 사용하시면 됩니다.

D. User Code 부분의 코드를 작성하신 후 서버에 제출하실 때, 디버깅을 위한 라이브러리 함수뿐 아니라 표준 입출력 함수를 모두 삭제 또는 주석 처리해 주셔야 합니다. 


문제 내에 제약조건을 모두 명시하지 않으므로 주어지는 코드를 분석하셔야 합니다.

코드는 개발 언어에 따라 상이할 수 있으므로, 작성할 언어를 기준으로 분석하셔야 합니다.

 


[문제 설명]

엑셀과 유사하게 간단한 수식을 지원하는 Table Calculator를 구현하고자 한다.

Table Calculator Table99개의 row 26개의 column으로 구성되며 각 영역을 cell 이라고 부른다.

[Fig. 1]과 같이 row index 는 숫자로, column index 는 알파벳 대문자로 나타내며,

cell 의 주소값은 column index row index를 순서대로 붙인 문자열로 나타낸다.


Table Calculator 는 각 cell 에 해당하는 값 또는 수식의 리스트를 받아 정확한 값을 계산하여 저장해야 한다. 수식이 주어지지 않는 cell 의 값은 0으로 간주한다.

[Fig. 2]10 cell 에 대한 입력에 따른 결과값의 예를 나타낸다.


 

아래 설명을 참조하여 Table Calculator 가 제공해야 하는 다음의 API들을 작성하라.


initTable()

 

void initTable()

 

 - test case 가 시작될 때마다 호출되는 함수로써 표를 초기화한다.

 

Parameters:

updateCell()

 

bool updateCell(int row, int col, char equation[], int value[][])

 

 - 특정 cell 의 값 또는 수식을 변경하고, 표의 모든 cell의 값을 갱신하여 리턴한다.

   row=0, col=0 인 경우 A1 cell 을 뜻하고, row=98, col=25 인 경우 Z99 cell 을 뜻한다.

 

Parameters:

 

row

[in] 수정할 cell row index (0 이상 98 이하)

 

col

[in] 수정할 cell column index (0 이상 25 이하)

 

equation

[in] 해당하는 cell 에 변경할 수식 또는 값

 

value

[out] 표의 전체 cell 에 대해 갱신한 결과 값

cell 의 결과 값은 100000007 로 나눈 나머지 값을 저장한다.

Returns:

 

true

모든 cell 이 정상적으로 계산된 경우

false

미결정 cell 이 존재하는 경우

 

 


                                                          [Table 1]


updateCell() 을 호출하는 과정에서 특정 cell 의 값을 결정하지 못하는 경우가 발생할 수 있으며, 이러한 cell 을 미결정 cell 이라 한다.

미결정 cell 은 다음과 같이 2가지 type 이 있다.


[Type 1. 순환 참조]

순환 참조란 수식의 참조 값이 맞물려 있는 경우를 말한다. 순환 참조는 [Fig. 3]과 같이 2 가지 경우로 발생할 수 있다.



- Case 1 : 자기 자신을 참조하는 경우

          * A1 cell 의 경우 자기 자신을 참조 하기 때문에 특정 값으로 결정할 수 없다.

- Case 2 : 2 개 이상의 cell 이 서로 순환하여 참조하는 경우

          * B2, C2 cell 의 경우 서로 순환(B2C2B2)하여 참조하고 있기 때문에 특정 값으로 결정할 수 없다.

          * A4, C4, E3 cell 의 경우 서로 순환(A4E3C4A4)하여 참조하고 있기 때문에 특정 값으로 결정할 수 없다.


[Type 2. 순환 참조 확장]

어떤 cell Type 1 의 순환 참조 cell 들 중 하나 이상을 참조하는 경우, cell 또한 미결정 cell 이다.

[Fig. 3]에서 B5의 경우, [Type 1] 미결정 cell A4 를 참조하기 때문에 미결정 cell 이다.

미결정 cell 여부는 수식의 연산을 처리하기 전에 결정된다.

[Fig. 3] C5와 같이 수식에서 [Type 1] 미결정 cell B2를 제거할 수 있는 경우에도 C5는 미결정 cell 이다.

[Fig. 3] D5와 같이 하나 이상의 [Type 2] 미결정 cell 을 참조해도 미결정 cell 이다. 


이와 같이 updateCell() 을 통해 cell 의 수식을 변경한 후 미결정 cell 이 하나 이상 존재하는 경우,
미결정 cell 의 총 개수 count 를 구하고, 미결정 cell 들의 값을 count 로 저장한다. 그리고 updateCell 함수는 false 를 리턴한다.


[Fig. 4]9번의 updateCell() 함수 수행 후, 10번째 updateCell(4, 4, “=A1+B5”, value) 함수를 호출한 이후의 예제를 나타낸다.


 

이는 [Type 1][Type 2] 에 해당하는 미결정 cell 과 정상적으로 계산 가능한 cell 을 포함하는 예제이다. cell 의 값은 아래와 같은 근거로 결정된다.

 - A1 : [Case 1]과 같은 미결정 cell

 - B2, C2 : [Case 2]와 같은 미결정 cell

 - A4, C4, E3 : [Case 2]와 같은 미결정 cell

 - E5 : [Type 1] 미결정 cell A1 을 참조하기 때문에 [Type 2] 미결정 cell

 - B5 : 39

 - D1 : -5

 - E1 : 39 - (-5) = 44

 - A1, B2, C2, A4, C4, E3, E5 : 미결정 cell 이 총 7개이므로 각 cell 의 값을 7로 저장

 - 나머지 cell : 수식이 존재하지 않기 때문에 0 저장

 - 미결정 cell 이 존재하기 때문에 false를 리턴 


그리고 updateCell(3, 0, “10”, value) 가 호출되면 [Fig. 5] 와 같이 표가 갱신된다.



   - A4 : updateCell() 함수 호출에 의해 10 으로 변경

- C4, E3 : 이제 미결정 cell 이 아니므로 값 계산

- A1, B2, C2, E5 : 미결정 cell 이 총 4개이므로 각 cell 값을 4로 저장

- 미결정 cell 이 존재하기 때문에 false를 리턴 


여기서 updateCell(0, 3, “=E1-10”, value) 가 호출되면 [Fig. 6]과 같이 표가 갱신된다.


 - D1, E1 : [Case 2] 와 같은 미결정 cell

 - A1, B2, C2, D1, E1, E5 : 미결정 cell이 총 6개이므로 각 cell 의 값을 6으로 저장

 - 미결정 cell 이 존재하기 때문에 false를 리턴 


[Fig. 7]은 입력으로 주어지는 equation의 다양한 형태를 나타낸다.

 


[제약 사항]

1. 입력되는 Table 의 크기는 가로 26 x 세로 99 이다.

2. updateCell() 함수의 "row" 파라미터는 0 이상 98 이하의 정수이다.

3. updateCell() 함수의 "col" 파라미터는 0 이상 25 이하의 정수이다.

4. cell 주소값의 row index 1 이상 99 이하의 정수이다.

5. cell 주소값의 column index ‘A’ 에서 ‘Z’까지의 알파벳 대문자 한 문자이다.

6. updateCell() 함수의 "equation" 파라미터는 아래 중 하나이다.

a. 1 이상 10000 이하의 양의 정수

b. -10000 이상 -1 이하의 음의 정수

c. 0 또는 -0

d. 수식

- 수식은 반드시 ‘=’ 기호로 시작한다.

- 수식에 사용되는 항의 최대 개수는 25 개이다.

- 수식의 각 항에는 특정 cell 의 주소값 또는 정수 값이 주어진다.

  (이때 정수값의 범위는 -10000 이상 10000 이하이다.)

- 연산자는 '+', '-' 만 허용한다. 곱셈, 나눗셈, 괄호 등의 기호는 입력되지 않는다.

- [Fig. 7] A4, B2와 같이 첫 번째 항이 '-' 로 시작하는 경우도 있다.

- 수식 문자열은 빈 칸 없이 모두 붙여져 있다.

- '+', '-' 연산자 2 개가 연속해서 입력되는 경우는 없다. (: E1--200, 200+-100, 1++2, 1-+A1)

7. [Fig. 7] D3, D4와 같이 수식이 주어지지 않는 cell0으로 저장한다.

8. [Fig. 7]D2와 같이 수식이 주어지지 않은 cell(D4)을 참조하는 경우, cell 0 으로 간주한다.

9. [Fig. 7]B3과 같이 한 cell 안에 동일한 cell 을 여러 번 참조할 수 있다.

10. 동일한 cell 에 대해서 updateCell() 함수가 여러 번 호출될 수 있다.

11. cell 을 계산하는 모든 과정 중의 값과 결과 값은 100000007로 나눈 나머지 값을 저장한다.

  (: A3+B3-C3+D3 (((((A3+B3)%100000007) - C3) % 100000007) + D3) % 100000007)

12. 수식의 연산 처리 순서는 결과 값에 영향을 주지 않는다.

13. 미결정 cell 여부는 수식의 연산을 처리하기 전에 결정된다. ([Fig. 3] C5 참조)

14. 하나의 Test case 에서 updateCell() 함수는 최대 2000 번 호출된다. 


[입력 / 출력]

입출력은 제공되는 Main 부분의 코드에서 처리하므로 User Code 부분의 코드에서는 별도로 입출력 함수를 사용해서는 안 된다.

Sample input에 대한 정답 출력 결과는 아래와 같은 형태로 보여진다.

#1 14                          // Test case #1 에 대한 정답 출력 예

#2 10                          // Test case #2

#3 12

#4 100

#5 540

TotalScore = 676


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdio.h>
 
#define WIDTH    26
#define HEIGHT    99
#define LENGTH    200
const int THRESHOLD = 100000007;
static int value[HEIGHT][WIDTH];
 
extern void initTable();
extern bool updateCell(int row, int col, char equation[LENGTH], int value[HEIGHT][WIDTH]);
 
int main_init(){
    for(int i = 0; i < HEIGHT; ++i){
        for(int j = 0; j < WIDTH; ++j){
            value[i][j] = 0;
        }
    }
    int cmd = 0;
    scanf("%d"&cmd);
    return cmd;
}
 
int calcChecksum(int value[HEIGHT][WIDTH], bool ret){
    int sum = 0;
    for(int i = 0; i < HEIGHT; ++i){
        for(int j = 0; j < WIDTH; ++j){            
            sum += value[i][j];
            sum %= THRESHOLD;
        }
    }
    if(!ret) ++sum;
    sum %= THRESHOLD;
    if(sum < 0) sum += THRESHOLD;
    return sum;
}
 
int main(){
    setbuf(stdout, NULL);
    //freopen("sample_input.txt", "r", stdin);
    
    int T;
    int totalScore = 0;
    scanf("%d"&T);
    for(int tc = 1; tc <= T; ++tc){
        initTable();
        int row, col;
        char input[LENGTH];
        int checksumIn = 0;
        int cmd = main_init();        
        int score = 0;
        
        for(int i = 0; i < cmd; ++i){
            scanf("%d %d %s %d"&row, &col, input, &checksumIn);        
            if(checksumIn < 0) checksumIn += THRESHOLD;
            bool ret = updateCell(row, col, input, value);
            int checksum = calcChecksum(value, ret);            
            if(checksumIn == checksum) ++score;
        }    
        printf("#%d %d\n", tc, score);
        totalScore += score;
    }
    printf("TotalScore = %d\n", totalScore);
 
    return 0;
}
cs

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define WIDTH    26
#define HEIGHT    99
#define LENGTH    200
const int THRESHOLD = 100000007;
char Table[HEIGHT][WIDTH][LENGTH];
 
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
 
void initTable(){
    // TO DO    
}
 
bool updateCell(int row, int col, char equation[LENGTH], int value[HEIGHT][WIDTH]){    
    // TO DO        
    
    return true; // Need to be changed
}
 
cs

 


'Computer Science' 카테고리의 다른 글

protocol  (0) 2019.05.17
중고차  (0) 2019.03.15
블록 조립  (0) 2019.03.15
Photo  (0) 2019.03.15
이미지 복원하기2  (0) 2019.03.15

댓글