Блог пользователя RemmargorP

Автор RemmargorP, 10 лет назад, По-русски

Задача:

Дана последовательность цифр. Нужно найти сумму всех возможных чисел, которые могут быть "склеены" из этих цифр на отрезке [L;R]

Если для хранения этих цифр использовать vector<char> data, то при вычислении (1LL * data[i] * p[i]) получается RE. Меняю на vector<int> — accepted.

Считывание у меня такое:

for (int i = 0; i < n; ++i) {
    scanf("%d", &data[i]);
}

Это связано с особенностью компилятора или я что-то сделал не так?

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

»
10 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

Если ты читаешь %d, то ты должен передать int* следущим аргументом, а не char*

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Я думал если число влезает в char, то он нормально его запишет. Спасибо)

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Дело в том, что scanf() вообще не знает, какого типа параметры ему переданы. Поэтому и надо в строке формата указывать разные %d, %s вместо %1, %2. Если сделать так:

      char c;
      scanf("%d", &c);
      

      то scanf() воспримет второй аргумент как указатель на int и запишет туда целый int (скорее всего, 4 байта вместо 1). Память, которая следует после c, окажется переписанной.

      Разные форматы можно посмотреть здесь: http://en.cppreference.com/w/cpp/io/c/fscanf. И ещё надо читать предупреждения компилятора.

»
10 лет назад, # |
  Проголосовать: нравится -34 Проголосовать: не нравится

Никогда не понимал людей, которые всюду суют сканфы и принтфы. Я могу вспомнить от силы 2 задачи, где это было действительно необходимо. Неужели это так забавно — ухудшать читаемость кода и еще к тому же ловить бредовые ошибки на ровном месте?

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +22 Проголосовать: не нравится

    Ну, я бы не сказал, что это ухудшает читаемость кода. При использовании scanf/printf сразу видишь, как выглядит ввод/вывод, в отличие от cin/cout, где нужно вспоминать какого типа переменная используется. Плюс вариант с printf может получиться на порядок короче, чем с cout (например, вывести время в формате часы:минуты:секунды).

    На счет "ловить бредовые ошибки" — есть warnings и хорошая привычка их не игнорировать.

    Ну а так да, cin/cout круче за счет статической типизации, что к тому же должно делать его быстрее scanf/printf.

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Я могу вспомнить от силы 2 задачи — а я могу вспомнить примерно 5 таких задач только за последние 2 недели:)

    Или есть способ заставить cin/cout нормально работать с long long и с точным выводом double? Я не умею. Понятно, что он намного быстрее scanf/printf для int'ов, но на этом преимущества заканчиваются.

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      А что за проблемы у cin/cout с long long и double?

      • »
        »
        »
        »
        10 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Ощутимое отставание в быстродействии по сравнению с printf/scanf. Можно посмотреть, например, эту тему.

        • »
          »
          »
          »
          »
          10 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Насчёт даблов действительно вижу оставание порядка 1.5 раза.

          А вот для long long получилось наоборот ускорение. В тестах из приведённой темы long long нет, возможно я что-то неправильно переписал, но вот эта программа выдаёт мне

          double, printf     7.89   7.97   7.75
          double, cout      10.90  11.09  10.86
          double, scanf      2.98   2.95   2.93
          double, cin        4.68   4.66   4.82
          long long, printf    1.40   1.41   1.39
          long long, cout    1.20   1.27   1.24
          long long, scanf    1.71   1.69   1.70
          long long, cin     1.12   1.11   1.11
          
    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Если точный вывод double, это вывод 8 знаков после запятой, то вот так:

      cout.precision(8);
      cout << fixed << x << endl;
      
      • »
        »
        »
        »
        10 лет назад, # ^ |
          Проголосовать: нравится +5 Проголосовать: не нравится

        в одну строчку удобнее и читабельнее

        printf("%.8lf\n", x);