2011-08-24 4 views
0

텍스트 :acm 문제가 발생했습니다. 내 코드에서 무엇이 잘못 되었습니까? 문제

입력 : 입력 스트림은 정수 번호 (AI ≤ 1,018 0 ≤ AI)의 세트를 포함한다. 숫자는 공백과 줄 바꿈으로 구분됩니다. 입력 스트림의 크기는 256KB를 초과하지 않습니다.

출력 : 마지막 숫자부터 각 숫자까지 첫 번째 숫자까지 Ai의 제곱근을 출력해야합니다. 각 제곱근은 소수점 이하 4 자리 이상의 별도 행에 인쇄해야합니다.

샘플
입력 :

 
1427 0

876652098643267843 5276538

출력 :

 
2297.0716 
936297014.1164 
0.0000 
37.7757

시간 제한 : 2.0 초
메모리 제한 : 16메가바이트

C와 C++ 프로그램에 의해 서버에 컴파일

32 비트 Microsoft Visual C++ 2010. 2010 년 8 월 3 일까지 Intel C++ Compiler 7.0이 사용되었습니다. 이 페이지에서 Microsoft Visual Studio 2010 Express 무료 사본을 다운로드 할 수 있습니다. 컴파일러는 다음과 같은 매개 변수와 함께 호출됩니다

#include <iostream> 
#include <list> 
#include <string> 
#include <sstream> 
#include <math.h> 
#include <algorithm> 
#include <iomanip> 
#include <stdio.h> 

void sqrt_f(double n) 
{ 
    printf ("%.4f\n", sqrt(static_cast<double>(n))); 
} 

int main() 
{ 
    std::list<double> numbers; 
    std::string sInput; 
    getline(std::cin, sInput); 
    std::istringstream parse(sInput); 
    double tmp; 
    while (parse >> tmp) 
     numbers.push_front(tmp); 
    std::for_each(numbers.begin(), numbers.end(), sqrt_f); 
    return 0; 
} 

그러나 심판의 결과는 다음과 같습니다 : 오답 (TEST1)

가 무엇의

// C 
cl /TC /MT /EHsc /O2 /W3 /Za /D "_CRT_SECURE_NO_WARNINGS" 
    /D "_CRT_SECURE_NO_DEPRECATE" /D "ONLINE_JUDGE" 

// C++ 
cl /TP /MT /EHsc /O2 /W3 /Za /D "_CRT_SECURE_NO_WARNINGS" 
    /D "_CRT_SECURE_NO_DEPRECATE" /D "ONLINE_JUDGE"

이 GCC 4.3이 문제의 내 솔루션입니다 문제?

+2

것 같습니다 : 고정 국기와 정밀도 모두가 "끈끈한"이기 때문에, 우리는 우리가 std::transform 전화 한 번 전에 포맷을 설정하여 올바른 형식의 모든 출력을 얻을 수 있습니다 입력의. 나는 당신이 그 이상을 읽고 싶어한다고 확신합니다. –

+0

코드 리뷰에 오신 것을 환영합니다! FAQ를 읽으면 여기에 제시된 코드가 작동하지만 스타일/성능 문제에 도움이 필요하다는 것을 알 수 있습니다. –

+0

@ Jeff의 의견에 덧붙여, 표시된 코드로 제공 한 샘플 입력을 처리하는 것처럼 보이지는 않습니다. –

답변

3

경고 : 내가 이것을 작성했을 때 질문은 여전히 ​​코드 검토 사이트에 있었기 때문에 주로 코드 검토로 작성되었습니다. SO에 주로 적용되는 부분 (입력 문제 해결)은 지나칠 때 겨우 언급됩니다. 순간

, 당신이 @Jeff 메르 카도는 같은 코드 뭔가 얻을 지적 문제 해결했다고 생각하는거야 그런 다음

#include <iostream> 
#include <list> 
#include <string> 
#include <sstream> 
#include <math.h> 
#include <algorithm> 
#include <iomanip> 
#include <stdio.h> 

void sqrt_f(double n) 
{ 
    printf ("%.4f\n", sqrt(static_cast<double>(n))); 
} 

int main() 
{ 
    std::list<double> numbers; 
    std::string sInput; 
    while (getline(std::cin, sInput)) { // added `while` to process all input 
     std::istringstream parse(sInput); 
     double tmp; 
     while (parse >> tmp) 
      numbers.push_front(tmp); 
    } 
    std::for_each(numbers.begin(), numbers.end(), sqrt_f); 
    return 0; 
} 

을, 나는 질문을 무시하는거야 당신은 실제로 (정확성에 대해) 물어보고 (재 작성된) 코드를 검토하여 요구 사항을 충족한다고 가정합니다. ++

  1. 의 printf를 사용하여 C에서 :
    void sqrt_f(double n) 
    { 
        printf ("%.4f\n", sqrt(static_cast<double>(n))); 
    } 
    

    은 내가 특별히 좋아하지 않아 여기에 세 가지를 참조하십시오. 일반적으로 iostream이 선호됩니다 (이 경우에는 더 자세한 정보가 표시됩니다).
  2. static_cast는 완전히 관계없는 것 같습니다 (n은 이미 두 배입니다).
  3. 우려의 불충분. 계산을 I/O와 결합합니다.

    std::list<double> numbers;

여기 std::list를 사용하는 많은 이유가 표시되지 않습니다.당신은 한쪽 끝에 만 삽입하고, 끝까지 이동합니다. std::list을 사용하는 주된 이유는 목록의 중간에 삽입/삭제하려는 경우입니다. 그렇다고하더라도 반드시 최선의 선택은 아니지만, 한 쪽 끝만 삽입하면 거의 틀린 선택입니다.

std::string sInput; 
while (getline(std::cin, sInput)) { // added `while` to process all input 
    double tmp; 
    while (parse >> tmp) 
     numbers.push_front(tmp); 
} 

여기서 std::getline을 사용하는 실제 이유는 없습니다. getline은 주로 입력에 줄 중심 서식이있는 경우 유용하지만 여기서는 임의의 양의 공백으로 구분 된 두 줄의 스트림입니다. 이를 위해 많은 기능을 얻지 않고도 추가 복잡성을 추가 한 것처럼 보입니다.

나는 루프 while (parse >> tmp)에 대해서도 흥분하지 않는다. 확실히 어떤 대안보다 낫지 만, std::copy (이 경우)을 사용하여 std::istream_iterator<double>을 사용하여 값을 콜렉션에 복사하십시오.

여기에 컬렉션을 사용하는 방법에 대해 특별히 흥분하지 않습니다. 먼저 push_front을 사용하여 주문을 취소합니다. 적어도 제게는 컬렉션에 숫자를 원래 순서대로 추가 한 다음 콜렉션을 거꾸로 지나친다면 이해하기가 더 쉬운 것처럼 보입니다.

std::for_each(numbers.begin(), numbers.end(), sqrt_f); 

... 여기에는 sqrt_f의 책임 분리에 대한 책임이 있습니다. STL이 C++에 이은 지 15 년이 지났습니다. 그 당시에는 std::for_each을 6 번이나 사용했는지 의심 스러웠습니다. 그것은 일 수 있습니다 유용하지만, 더 나은 다른 작품을 찾을 수없는 경우 일반적으로 알고리즘의 마지막 선택해야합니다.

만약 내가 이것을하고 있었다면, std::vector을 스토리지에 사용한다고 생각합니다. 우리는 한쪽 끝에 항목을 추가하면됩니다 (vector에 해당). std :: cin에서 직접 데이터를 std::copystd::istream_iterator<double>을 사용하는 해당 벡터로 복사합니다. 그런 다음 벡터에 대해 역 반복기 쌍을 사용하여 std::transform을 사용하고 출력에는 ostream_iterator을 사용합니다. 당신이 첫 번째 라인을 읽는 것 같은

std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield); 
std::cout.precision(4); 
관련 문제