printf против cout
От: olimp_20  
Дата: 28.06.15 10:02
Оценка:
Условие задачи
  Решение с помощью printf
#include <stdio.h>
#include <vector>
#include <cmath>
using namespace std;

double cv[7];//вектор значений емкостей конденсаторов
double C;//эталонное значение
double CAnsw;//ответ на задачу


void f(double* cv, int n);

//функции вычисления мин. значения, согласно условию задачи (сравнение с С)
double min2d(double a, double b);
double min3d(double a, double b, double c);

//------------------------------------------------------
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    int n;
    scanf("%d", &n);

    scanf("%Lf", &C);

    for(int i=0; i<n; ++i)
        scanf("%Lf", &cv[i]);

    CAnsw = cv[0];
    for(int i=1; i<n; ++i)
        CAnsw = min2d(CAnsw, cv[i]);

    f(cv, n);
    
    printf("%0.6Lf\n", CAnsw);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    return 0;
}
//------------------------------------------------------
//------------------------------------------------------
void f(double* cv, int n){
    for(int i=0; i<n-1; ++i)//перебрать все пары конденсаторов из cv
        for(int j=i+1; j<n; ++j){

            double c1 = cv[i] + cv[j];//параллельное соединение
            double c2 = (cv[i] * cv[j]) / c1; //последовательное соединение

            CAnsw = min3d(CAnsw, c1, c2);

            //создание новой последовательности без cv[i] и cv[j]
            double cvSmall[7];
            int k(0);
            for(int z(0); z<n; ++z)
                if(z!=i && z!=j) {cvSmall[k]=cv[z]; ++k;}

            cvSmall[k]=c1;
            f(cvSmall, k+1);//новая последовательность и с1

            cvSmall[k]=c2;
            f(cvSmall, k+1);//новая последовательность и с2
        }
}

//------------------------------------------------------
double min2d(double a, double b){
    return fabs(C-b)-fabs(C-a)>=0.0 ? a : b;
}

//------------------------------------------------------
double min3d(double a, double b, double c){
    return fabs(C-b)-fabs(C-a)>=0.0 ? min2d(a, c) : min2d(b, c);
}

на все тесты сообщает: неправильный ответ.
  А решение с fstream+iomanip
#include <fstream>
#include <iomanip>

#include <vector>
#include <cmath>
using namespace std;

double cv[7];//вектор значений емкостей конденсаторов
double C;//эталонное значение
double CAnsw;//ответ на задачу


void f(double* cv, int n);

//функции вычисления мин. значения, согласно условию задачи (сравнение с С)
double min2d(double a, double b);
double min3d(double a, double b, double c);

//------------------------------------------------------
int main()
{
    ifstream fileIn("input.txt");
    ofstream fileOut("output.txt");

    fileOut.setf(ios::fixed);
    fileOut.precision(6);

    int n;
    fileIn >> n;

    fileIn >> C;

    for(int i=0; i<n; ++i)
    fileIn >> cv[i];

    CAnsw = cv[0];
    for(int i=1; i<n; ++i)
        CAnsw = min2d(CAnsw, cv[i]);

    f(cv, n);

    fileOut << CAnsw << '\n';
    fileIn.close();
    fileOut.close();

    return 0;
}
//------------------------------------------------------
//------------------------------------------------------
void f(double* cv, int n){
    for(int i=0; i<n-1; ++i)//перебрать все пары конденсаторов из cv
        for(int j=i+1; j<n; ++j){

            double c1 = cv[i] + cv[j];//параллельное соединение
            double c2 = (cv[i] * cv[j]) / c1; //последовательное соединение

            CAnsw = min3d(CAnsw, c1, c2);

            //создание новой последовательности без cv[i] и cv[j]
            double cvSmall[7];
            int k(0);
            for(int z(0); z<n; ++z)
                if(z!=i && z!=j) {cvSmall[k]=cv[z]; ++k;}

            cvSmall[k]=c1;
            f(cvSmall, k+1);//новая последовательность и с1

            cvSmall[k]=c2;
            f(cvSmall, k+1);//новая последовательность и с2
        }
}

//------------------------------------------------------
double min2d(double a, double b){
    return fabs(C-b)-fabs(C-a)>=0.0 ? a : b;
}

//------------------------------------------------------
double min3d(double a, double b, double c){
    return fabs(C-b)-fabs(C-a)>=0.0 ? min2d(a, c) : min2d(b, c);
}

успешно решает задачу.
Подскажите, что неправильно в первом варианте, как исправить?
Re: printf против cout
От: VTT http://vtt.to
Дата: 28.06.15 10:33
Оценка:
Здравствуйте, olimp_20, Вы писали:

  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);

Отличие, которое сразу бросается в глаза, это переоткрывание стандартных потоков. Зачем там freopen, когда есть fopen?
И завязывайте с практикой использования однобуквенных переменных...
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[2]: printf против cout
От: olimp_20  
Дата: 28.06.15 10:45
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Здравствуйте, olimp_20, Вы писали:


VTT>
VTT>  freopen("input.txt", "r", stdin);
VTT>  freopen("output.txt", "w", stdout);
VTT>

VTT>Отличие, которое сразу бросается в глаза, это переоткрывание стандартных потоков. Зачем там freopen, когда есть fopen?
VTT>И завязывайте с практикой использования однобуквенных переменных...

Вы по своему правы, но такое использование адаптировано мной под серверы олимпиадных задач:
1) строки с freopen при отправке на сервер закомментированы ;
2) в результате происходит более быстрое чтение/запись через scanf/printf : для некоторых задач, как оказывается — это существенно.
Я согласен, что такой подход может вызывать споры, но вопрос состоял в другом: можно ли написать вывод с помощью printf , чтобы он на том же сервере прошел так же успешно, как и cout? Если возможно, то как? (Поэтому для обсуждения было представлено оба кода.)
Re: printf против cout
От: BulatZiganshin  
Дата: 28.06.15 11:18
Оценка:
Здравствуйте, olimp_20, Вы писали:

_> printf("%0.6Lf\n", CAnsw);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


а это вообще работает? inet говорит что %Lf — это long double
Люди, я люблю вас! Будьте бдительны!!!
Re: printf против cout
От: pagid Россия  
Дата: 28.06.15 13:01
Оценка:
Здравствуйте, olimp_20, Вы писали:

_>Подскажите, что неправильно в первом варианте, как исправить?


Префикс формата "l" в scanf и print должет быть строчной буквой

 scanf("%lf", &C);
...
...
 printf("%0.6lf\n", CAnsw);
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Re[2]: printf против cout
От: olimp_20  
Дата: 28.06.15 13:04
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>Здравствуйте, olimp_20, Вы писали:


_>> printf("%0.6Lf\n", CAnsw);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


BZ>а это вообще работает? inet говорит что %Lf — это long double

и так работает, и так — printf("%0.6f\n", CAnsw);

в VС++ 2010 — всё работает...на сервере — нет...
Re[2]: printf против cout
От: olimp_20  
Дата: 28.06.15 13:07
Оценка: -1
Здравствуйте, pagid, Вы писали:

P>Здравствуйте, olimp_20, Вы писали:


_>>Подскажите, что неправильно в первом варианте, как исправить?


P>Префикс формата "l" в scanf и print должет быть строчной буквой


P>
P> scanf("%lf", &C);
P>...
P>...
P> printf("%0.6lf\n", CAnsw);
P>


да без разницы компилятору
Re[3]: printf против cout
От: pagid Россия  
Дата: 28.06.15 13:14
Оценка:
Здравствуйте, olimp_20, Вы писали:

_>да без разницы компилятору

Которому? локально на VС++ 2010 проверял тоже без разницы. А GNU C++ не без разницы.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Re[4]: printf против cout
От: olimp_20  
Дата: 28.06.15 13:47
Оценка:
Здравствуйте, pagid, Вы писали:

P>Которому? локально на VС++ 2010 проверял тоже без разницы. А GNU C++ не без разницы.


На сервере я проверял:
1)
long long a = CAnsw;
    long long b = (CAnsw - a) * 1000000;
    printf("%lld,%lld\n", a,b);

2)
    long long a = CAnsw;
    long long b = (CAnsw - a) * 10000000;
    if(b%10>=5) b = b/10+1; else b =b/10;
    printf("%lld.%lld\n", a,b);

3)
printf("%0.6lf\n", CAnsw);

4)
printf("%0.6Lf\n", CAnsw);

5)
printf("%0.6llf\n", CAnsw);

6)
printf("%Lf\n", CAnsw);

7)
printf("%lf\n", CAnsw);


а всюду результат — "Неправильный ответ"
Re[5]: printf против cout
От: pagid Россия  
Дата: 28.06.15 14:10
Оценка: 3 (1)
Здравствуйте, olimp_20, Вы писали:

_>а всюду результат — "Неправильный ответ"

а scanf ?

Разница между MS VC и GNU C в том, что long double для MS VC имеет то же двоичное предствление, что и double (типы разные), а для GNU C++ long double 80-битовый. По префиксу "L" как раз printf и scanf ожидают/сохраняют long double, а по "l" — double. Без префикса — 32-разрядный float.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Re[6]: printf против cout
От: olimp_20  
Дата: 28.06.15 14:24
Оценка:
Здравствуйте, pagid, Вы писали:

P>а scanf ?


P>Разница между MS VC и GNU C в том, что long double для MS VC имеет то же двоичное предствление, что и double (типы разные), а для GNU C++ long double 80-битовый. По префиксу "L" как раз printf и scanf ожидают/сохраняют long double, а по "l" — double. Без префикса — 32-разрядный float.


Спасибо Вам. Прощу прощения за предыдущие возражения. Все получается, если:
    scanf("%lf", &C);
 
    for(int i=0; i<n; ++i)
        scanf("%lf", &cv[i]);

и
printf("%0.6lf\n", CAnsw);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.