понедельник, 14 марта 2011 г.

Операторы цикла

Цикл While. Блок 3. Анализ цифр числа.

Задача A. Сумма цифр числа
Дано натуральное число N. Напишите функцию int SumOfDigits (int n), вычисляющую сумму цифр числа N.

  1. int SumOfDigits (int n)
  2. {
  3.   int sum = 0;
  4.   while (n)
  5.   {
  6.     sum += n % 10;
  7.     n /= 10;
  8.   }
  9.   return sum;
  10. }
* This source code was highlighted with Source Code Highlighter.


Задача B. Количество нулей
Дано натуральное число N. Напишите функцию int NumberOfZeroes(int n), определяющую количество нулей среди всех цифр числа N.

  1. int NumberOfZeroes(int n)
  2. {
  3.   int count = 0;
  4.   while (n)
  5.   {
  6.     if (n % 10 == 0)
  7.       count++;
  8.     n /= 10;
  9.   }
  10.   return count;
  11. }
* This source code was highlighted with Source Code Highlighter.


Задача C. Минимальная и максимальная цифры
Дано натуральное число N. Напишите функцию int MinDigit (int n)  и int MaxDigit (int n), определяющие наименьшую и наибольшую цифры данного числа.
Необходимо вывести наименьшую и наибольшую цифры данного числа через пробел.

  1. int MinDigit (int n)
  2. {
  3.   int cur;
  4.   int min_n = 9;
  5.   while (n)
  6.   {
  7.     cur = n % 10;
  8.     min_n = min(min_n,cur);
  9.     n /= 10;
  10.   }
  11.   return min_n;
  12. }
  13. int MaxDigit (int n)
  14. {
  15.   int cur;
  16.   int max_n = 0;
  17.   while (n)
  18.   {
  19.     cur = n % 10;
  20.     max_n = max(max_n,cur);
  21.     n /= 10;
  22.   }
  23.   return max_n;
  24. }
* This source code was highlighted with Source Code Highlighter.


Задача D. Двоичная запись
Дано натуральное число N. Выведите его представление в двоичном виде в обратном порядке.

  1.   int n;
  2.   cin >> n;
  3.  
  4.   while (n)
  5.   {
  6.     cout << n % 2;
  7.     n >>= 1;
  8.   }
  9.   cout << n;
* This source code was highlighted with Source Code Highlighter.


Задача E. Обращение числа
Напишите функцию int reverse(int n), которая переставляет цифры числа в обратном порядке .

Вариант 1. Если перевернутое число не требуется оформлять как отдельную переменную, то можно, просто откусывая последние цифры исходного числа, выписывать их в строку вывода .

  1. int reverse(int n)
  2. {
  3.   do
  4.   {
  5.     cout << n % 10;
  6.     n /= 10;
  7.   }
  8.   while (n);
  9.   return 0;
  10. }
* This source code was highlighted with Source Code Highlighter.

Вариант 2. Но можно и завести отдельную переменную под перевертыш, тогда появится возможность при необходимости использовать результат в дальнейшем.

  1. int reverse(int n)
  2. {
  3.   int rev = 0;
  4.   do
  5.   {
  6.     rev = rev * 10 + n % 10;
  7.     n /= 10;
  8.   }
  9.   while (n);
  10.   return rev;
  11. }
* This source code was highlighted with Source Code Highlighter.


Задача F. Количество палиндромов
Назовем число палиндромом, если оно не меняется при перестановке его цифр в обратном порядке. Напишите функцию bool IsPalindrome (int n), проверяющую по данному числу n, является ли оно палиндромом.
Напишите программу, которая по заданному числу K выводит количество натуральных палиндромов, не превосходящих K.

  1. bool IsPalindrome (int cur)
  2. {
  3.   int base = cur;
  4.   int rev = 0;
  5.   while (cur)
  6.   {
  7.     rev = rev * 10 + cur % 10;
  8.     cur /= 10;
  9.   }
  10.   if (base == rev)
  11.     return true;
  12.   else
  13.     return false;
  14. }
  15. int main()
  16. {
  17.   freopen("input.txt","r",stdin);
  18.   freopen("output.txt","w",stdout);
  19.  
  20.  int n;
  21.   cin >> n;
  22.   int cur = 1, count = 0;
  23.  
  24.   while (cur <= n)
  25.   {
  26.     if (IsPalindrome (cur))
  27.       count++;
  28.     cur++;
  29.   }
  30.   cout << count;
* This source code was highlighted with Source Code Highlighter.

Операторы цикла

Цикл While. Блок 2. Обработка последовательностей, индуктивные функции.

Задача A. Длина последовательности
Программа получает на вход последовательность целых неотрицательных чисел, каждое число записано в отдельной строке. Последовательность завершается числом 0, при считывании которого программа должна закончить свою работу и вывести количество членов последовательности (не считая завершающего числа 0).
Числа, следующие за числом 0, считывать не нужно.

  1.   int x, length = -1;
  2.   do
  3.   {
  4.     length++;
  5.     cin>>x;
  6.   }
  7.   while (x);
  8.   cout << length;
* This source code was highlighted with Source Code Highlighter.


Задача B. Сумма последовательности
Определите сумму всех элементов последовательности, завершающейся числом 0.
Числа, следующие за нулем, считывать не нужно.

  1.   int x, sum = 0;
  2.   cin >> x;
  3.   while (x)
  4.   {
  5.     sum += x;
  6.     cin >> x;
  7.   }
  8.   cout << sum;
* This source code was highlighted with Source Code Highlighter.


Задача C. Среднее значение последовательности
Определите среднее значение всех элементов последовательности, завершающейся числом 0.
Числа, следующие за нулем, считывать не нужно.

  1.   int x, sum = 0, length = 0;
  2.   while (cin>>x && x)
  3.   {
  4.     sum += x;
  5.     length++;
  6.   }
  7.   double rms = (double)sum / length;
  8.   printf("%0.15f",rms);
* This source code was highlighted with Source Code Highlighter.


Задача D. Количество четных элементов последовательности
Определите количество четных элементов в последовательности, завершающейся числом 0.
Само число 0, и все, что следует за ним, учитывать не нужно.

  1.   int x, count = 0;
  2.   cin >> x;
  3.   while (x)
  4.   {
  5.     if (!(x & 1))
  6.       count++;
  7.     cin >> x;
  8.   }
  9.   cout << count;
* This source code was highlighted with Source Code Highlighter.


Задача E. Максимум последовательности
Последовательность состоит из натуральных чисел и завершается числом 0. Определите значение наибольшего элемента последовательности.
Числа, следующие за нулем, считывать не нужно.

  1.   int x;
  2.   cin >> x;
  3.   int Max = x;
  4.   while (x)
  5.   {
  6.     Max = max(Max,x);
  7.     cin >> x;    
  8.   }
  9.   cout << Max;
* This source code was highlighted with Source Code Highlighter.


Задача F. Количество элементов, которые больше предыдущего
Последовательность состоит из натуральных чисел и завершается числом 0. Определите, сколько элементов этой последовательности больше предыдущего элемента.
Числа, следующие за числом 0, считывать не нужно.

  1.   int prv, cur;
  2.   cin >> cur;
  3.   int count = 0;
  4.   while (cur)
  5.   {
  6.     prv = cur;
  7.     cin >> cur; 
  8.     if (cur > prv)
  9.       count++;
  10.   }
  11.   cout << count;
* This source code was highlighted with Source Code Highlighter.


Задача G. Второй максимум
Последовательность состоит из различных натуральных чисел и завершается числом 0. Определите значение второго по величине элемента в этой последовательности.
Числа, следующие за числом 0, считывать не нужно.

  1.   int x;
  2.   cin >> x;
  3.   int max1 = x, max2 = -1;
  4.   while (x)
  5.   {
  6.     cin >> x;
  7.     if (x > max1)
  8.     {
  9.       max2 = max1;
  10.       max1 = x;
  11.     }
  12.     else if ( x > max2 )
  13.       max2 = x;
  14.   }
  15.   cout << max2;
* This source code was highlighted with Source Code Highlighter.


Задача H. Второй максимум – 2
Последовательность состоит из натуральных чисел и завершается числом 0. Определите значение второго по величине элемента в этой последовательности, то есть элемента, который будет наибольшим, если из последовательности удалить наибольший элемент.
Числа, следующие за числом 0, считывать не нужно.

  1.   int x;
  2.   cin >> x;
  3.   int max1 = x, max2 = -1;
  4.   while (x)
  5.   {
  6.     cin >> x;
  7.     if (x > max1)
  8.     {
  9.       max2 = max1;
  10.       max1 = x;
  11.     }
  12.     else if ( x > max2 )
  13.       max2 = x;
  14.   }
  15.   cout << max2;
* This source code was highlighted with Source Code Highlighter.


Задача I. Количество элементов, равных максимуму
Последовательность состоит из натуральных чисел и завершается числом 0. Определите, какое количество элементов этой последовательности, равны ее наибольшему элементу.
Числа, следующие за числом 0, считывать не нужно.

  1.   int x, count = 0;
  2.   cin >> x;
  3.   int max = x;
  4.   while (x)
  5.   {
  6.     if (x > max)
  7.     {
  8.       max = x;
  9.       count = 1;
  10.     }
  11.     else
  12.       if (x == max)
  13.         count++;
  14.     cin >> x;    
  15.   }
  16.   cout << count;
* This source code was highlighted with Source Code Highlighter.


Задача J. Сумма последовательности – 2
Найдите сумму последовательности натуральных чисел, если признаком окончания конца последовательности является два подряд идущих числа 0.
Числа, следующие после двух подряд идущих нулей считывать не нужно.

  1.   int x;
  2.   cin >> x;
  3.   int sum = 0;
  4.   if (x == 0)
  5.     cin >> x;
  6.   while (x)
  7.   {
  8.     sum += x;
  9.     cin >> x;
  10.     if (x == 0)
  11.       cin >> x;
  12.   }
  13.   cout << sum;
* This source code was highlighted with Source Code Highlighter.


Задача K. Максимальное число идущих подряд равных элементов
Дана последовательность натуральных чисел, завершающаяся числом 0. Определите, какое наибольшее число подряд идущих элементов этой последовательности равны друг другу.
Числа, следующие за числом 0, считывать не нужно.

  1.   int cur;
  2.   cin >> cur;
  3.   int base = cur, count = 0, count_max = 0;
  4.   while (cur)
  5.   {
  6.     if (base == cur)
  7.       count++;
  8.     else
  9.     {
  10.       base = cur;
  11.       count = 1;
  12.     }
  13.     count_max = max(count_max, count);
  14.     cin >> cur;
  15.   }
  16.   cout << count_max;
* This source code was highlighted with Source Code Highlighter.


Задача L. Максимальная длина монотонного фрагмента
Дана последовательность натуральных чисел, завершающаяся число 0. Определите наибольшую длину монотонного фрагмента последовательности (то есть такого фрагмента, где все элементы либо больше предыдущего, либо меньше).
Числа, следующие за числом 0, считывать не нужно.

  1.   int prv, cur;
  2.   cin >> prv;
  3.   if (prv)
  4.   {
  5.     cin >> cur;
  6.     int count = 1, count_max = 1;
  7.     int sgn_prv = cur - prv, sgn_cur;
  8.  
  9.     while (cur)
  10.     {
  11.       sgn_cur = cur - prv;
  12.       if (sgn_prv * sgn_cur > 0)
  13.         count++;
  14.       else
  15.         if (sgn_prv * sgn_cur == 0)
  16.           count = 1;
  17.         else
  18.           count = 2;
  19.       count_max = max(count_max, count);
  20.       sgn_prv = sgn_cur;
  21.       prv = cur;
  22.       cin >> cur;
  23.     }
  24.     cout << count_max;
  25.   }
  26.   else
  27.     cout << 0;
* This source code was highlighted with Source Code Highlighter.


Задача M. Количество локальных максимумов
Элемент последовательности называется локальным максимумом, если он строго больше предыдущего и последующего элемента последовательности. Первый и последний элемент последовательности не являются локальными максимумами.
Дана последовательность натуральных чисел, завершающаяся числом 0. Определите количество строгих локальных максимумов в этой последовательности.
Числа, следующие за числом 0, считывать не нужно.

  1.   int prv, cur, nxt;
  2.   int count = 0;
  3.   if (cin>>prv && prv)
  4.   {
  5.     if (cin >> cur && cur)
  6.     {
  7.       if (cin >> nxt)
  8.       {
  9.         while (nxt)
  10.         {
  11.           if ((prv < cur) && (cur > nxt))
  12.             count++;
  13.           prv = cur;
  14.           cur = nxt;
  15.           cin >> nxt;
  16.         }
  17.       }
  18.     }
  19.   }
  20.   cout << count;
* This source code was highlighted with Source Code Highlighter.


Задача N. Наименьшее расстояние между локальными максимумами
Определите наименьшее расстояние между двумя локальными максимумами последовательности натуральных чисел, завершающейся числом 0. Если в последовательности нет двух локальных максимумов, выведите число 0.

  1.   int prv, cur, nxt, pos = 0, prv_max = 0, min_len = 0, cur_len;
  2.   int count = 0;
  3.   if (cin>>prv && prv)
  4.   {
  5.     if (cin >> cur && cur)
  6.     {
  7.       if (cin >> nxt)
  8.       {
  9.         pos = 2;
  10.         while (nxt)
  11.         {
  12.           if ((prv < cur) && (cur > nxt))
  13.           {
  14.             if (prv_max != 0 )
  15.             {
  16.               cur_len = pos - prv_max;
  17.               if (min_len == 0)
  18.                 min_len = cur_len;
  19.               else
  20.                 min_len = min(min_len,cur_len);
  21.             }
  22.             prv_max = pos;
  23.           }
  24.           prv = cur;
  25.           cur = nxt;
  26.           cin >> nxt;
  27.           pos++;
  28.  
  29.         }
  30.       }
  31.     }
  32.   }
  33.   cout<<min_len;
* This source code was highlighted with Source Code Highlighter.


Задача O. Стандартное отклонение

Дана последовательность натуральных чисел x1, x2, ..., xn. Стандартным отклонением называется величина
1
где2 —среднее арифметическое последовательности.

Определите среднеквадратичное отклонение для данной последовательности натуральных чисел, завершающейся числом 0.

  1.   int x;
  2.   cin >> x;
  3.   int  sum_x = 0, sum_x2 = 0, n = 0;
  4.   double s, res;
  5.   if(x)
  6.   {
  7.     while (x)
  8.     {
  9.       sum_x += x;
  10.       sum_x2 += x*x;
  11.       n++;
  12.       cin >> x;
  13.     }
  14.     s = (double)sum_x / n;
  15.     if (n != 1)
  16.     {
  17.       res = sqrt((sum_x2 - 2 * s * sum_x + n * s * s) / (n - 1));
  18.       printf("%0.11f", res);
  19.     }
  20.     else
  21.       cout << 0;
  22.   }
* This source code was highlighted with Source Code Highlighter.

Операторы цикла

Цикл While. Блок 1. Задачи на цикл While.

Задача A. Список квадратов
Выведите все точные квадраты натуральных чисел, не превосходящие данного числа N.

  1.   int n;
  2.   cin>>n;
  3.   int value = 1;
  4.   int curSqr = value*value;
  5.   while (curSqr<=n)
  6.   {
  7.     cout<<curSqr<<' ';
  8.     value++;
  9.     curSqr = value*value;
  10.   }
* This source code was highlighted with Source Code Highlighter.


Задача B. Минимальный делитель
Дано целое число, не меньшее 2. Выведите его наименьший натуральный делитель, отличный от 1.

  1.   int n;
  2.   cin >> n;
  3.   int i = 2, min_den = 1;
  4.   int sqrt_n = sqrt((double)n);
  5.   while (i <= sqrt_n)
  6.   {
  7.     if (n % i == 0)
  8.     {
  9.       min_den = i;
  10.       break;
  11.     }
  12.     i++;
  13.   }
  14.   if (min_den == 1)
  15.     cout << n;
  16.   else
  17.     cout << min_den;
* This source code was highlighted with Source Code Highlighter.


Задача C. Список степеней двойки
По данному числу N распечатайте все целые степени двойки, не превосходящие N, в порядке возрастания. Операцией возведения в степень пользоваться нельзя!

Вариант 1.

  1.   int n;
  2.   cin >> n;
  3.  
  4.   int pow2 = 1;
  5.   while (pow2 <= n)
  6.   {
  7.     cout << pow2 <<' ';
  8.     pow2 *=2;
  9.   }
* This source code was highlighted with Source Code Highlighter.

Той же  самой цели можно добиться, заменив явное умножение на 2 побитовым сдвигом.
Вариант 2.

  1.   int n;
  2.   cin >> n;
  3.  
  4.   int pow2 = 1;
  5.   while (pow2 <= n)
  6.   {
  7.     cout << pow2 <<' ';
  8.     pow2 <<= 1;
  9.   }
* This source code was highlighted with Source Code Highlighter.


Задача D. Точная степень двойки
Дано натуральное число N. Выведите слово YES, если число N является точной степенью двойки, или слово NO в противном случае. Операцией возведения в степень пользоваться нельзя!

  1.   int n;
  2.   cin>>n;
  3.   int bitAmount = 0;
  4.   while (n) {
  5.     bitAmount += n % 2;
  6.     n /= 2;
  7.   }
  8.   if (bitAmount == 1)
  9.     cout<<"YES";
  10.   else
  11.     cout<<"NO";
* This source code was highlighted with Source Code Highlighter.


Задача E. Двоичный логарифм
По данному натуральному числу N выведите такое наименьшее целое число k, что 2k≥N.
Операцией возведения в степень пользоваться нельзя!

  1.   int n;
  2.   cin >> n;
  3.  
  4.   int pow2 = 1, k = 0;
  5.   while (pow2 < n)
  6.   {
  7.     pow2 <<=1;
  8.     k++;
  9.   }
  10.   cout << k;
* This source code was highlighted with Source Code Highlighter.


Задача F. Утренняя пробежка
В первый день спортсмен пробежал x километров, а затем он каждый день увеличивал пробег на 10% от предыдущего значения. По данному числу y определите номер дня, на который пробег спортсмена составит не менее y километров.
Программа получает на вход действительные числа x и y и должна вывести одно натуральное число.

  1.   double x, y;
  2.   cin >> x >> y;
  3.   int k = 1;
  4.  
  5.   while (x < y)
  6.   {
  7.     x *= 1.1;
  8.     k++;
  9.   }
  10.   cout << k;
* This source code was highlighted with Source Code Highlighter.


Задача G. Банковские проценты
Вклад в банке составляет x рублей. Ежегодно он увеличивается на p процентов, после чего дробная часть копеек отбрасывается. Каждый год сумма вклада становится больше. Определите, через сколько лет вклад составит не менее y рублей.
Программа получает на вход три натуральных числа: x, p, y и должна вывести одно целое число.

  1.   double x,p,y;
  2.   int years = 0;
  3.   cin>>x>>p>>y;
  4.   while (x<y) {
  5.     x *= (1 + p/100.0);
  6.     x *= 100;
  7.     x = (int) x;
  8.     x /= 100;
  9.     years++;
  10.   }
  11.   cout<<years;
* This source code was highlighted with Source Code Highlighter.


Задача H. Числа Фибоначчи
Последовательность Фибоначчи определяется так: φ0=0,  φ1=1, ..., φnn-1n-2.
По данному числу n определите n-е число Фибоначчи φn.

  1.   int n, i = 2, f1 = 0, f2 = 1, cur;
  2.   cin >> n;
  3.  
  4.   while (i <= n)
  5.   {
  6.     cur = f1 + f2;
  7.     f1 = f2;
  8.     f2 = cur;
  9.     i++;
  10.   }
  11.   if (n<=1)
  12.     cout<<n;
  13.   else
  14.     cout << cur;
* This source code was highlighted with Source Code Highlighter.


Задача I. Номер числа Фибоначчи
Дано натуральное число A. Определите, каким по счету числом Фибоначчи оно является, то есть выведите такое число n, что φn=A. Если А не является числом Фибоначчи, выведите число -1.

  1.   int a, i = 1, f1 = 0, f2 = 1, cur = 1;
  2.   cin >> a;
  3.  
  4.   while (cur < a)
  5.   {
  6.     cur = f1 + f2;
  7.     f1 = f2;
  8.     f2 = cur;
  9.     i++;
  10.   }
  11.   if (cur == a)
  12.     cout << i;
  13.   else
  14.     cout << -1;
* This source code was highlighted with Source Code Highlighter.


Задача J. Исполнитель Раздвоитель
Исполнитель “Раздвоитель” преобразует натуральные числа. У него есть две команды: “Вычесть 1” и “Разделить на 2”, первая команда уменьшает число на 1, вторая команда уменьшает число в два раза, если оно чётное, иначе происходит ошибка.
Дано два натуральных числа A и B (A>B). Напишите алгоритм для Раздвоителя, который преобразует число A в число B и при этом содержит минимальное число команд. Команды алгоритма нужно выводить по одной в строке, первая команда обозначается, как -1, вторая команда как :2.

  1.   int a, b;
  2.   cin >> a >> b;
  3.  
  4.   while (a > b)
  5.   {
  6.     if (a % 2 == 0 && a / 2 >= b)
  7.     {
  8.       cout << ":2" << endl;
  9.         a /= 2;
  10.     }
  11.     else
  12.     {
  13.       cout << -1 << endl;
  14.       a--;
  15.     }
  16.   }
* This source code was highlighted with Source Code Highlighter.


Задача K. Исполнитель Водолей
У исполнителя “Водолей” есть два сосуда, первый объемом A литров, второй объемом B литров, а также кран с водой. Водолей может выполнять следующие операции:
Наполнить сосуд A (обозначается >A).
Наполнить сосуд B (обозначается >B).
Вылить воду из сосуда A (обозначается A>).
Вылить воду из сосуда B (обозначается B>).
Перелить воду из сосуда A в сосуд B (обозначается как A>B).
Перелить воду из сосуда B в сосуд A (обозначается как B>A).
Команда переливания из одного сосуда в другой приводят к тому, что либо первый сосуд полностью опустошается, либо второй сосуд полностью наполняется.
Программа получает на вход три натуральных числа A, B, N, не превосходящих 104 Вам необходимо вывести алгоритм действий Водолея, который позволяет получить в точности N литров в одном из сосудов, если же такого алгоритма не существует, то программа должна вывести текст Impossible. Количество операций в алгоритме не должно превышать 105. Гарантируется, что если задача имеет решение, то есть решение, которое содержит не более, чем 105 операций.

  1.   const int LIMIT = 1e5 + 10;
  2.   int a, b, n;
  3.   cin >> a >> b >> n;
  4.   char min = 'A', max = 'B';
  5.   bool real = false;
  6.   if (b < a)
  7.   {
  8.     swap(a, b);
  9.     swap(min, max);
  10.   }
  11.   int bV = 0, aV = 0;
  12.  
  13.   int k = 0;
  14.   do
  15.   {
  16.     k++; /*printf(">%c\n",min);*/       
  17.     k++; /*printf("%c>%c\n", min, max);*/   
  18.     if (b - bV >= a)
  19.       bV += a;
  20.     else
  21.     {
  22.       bV = a - (b - bV);
  23.       k++; /*printf("%c>\n",max);*/    
  24.       k++; /*printf("%c>%c\n", min, max);*/ 
  25.     }
  26.     if (n == bV)
  27.     {
  28.       real = true;
  29.       break;
  30.     }
  31.   }
  32.   while(k <= LIMIT);
  33.  
  34.   if (real)
  35.   {
  36.     bV = 0;
  37.     do
  38.     {
  39.       printf(">%c\n",min);       
  40.       printf("%c>%c\n", min, max);   
  41.       if (b - bV >= a)
  42.         bV += a;
  43.       else
  44.       {
  45.         bV = a - (b - bV);
  46.         printf("%c>\n",max);     
  47.         printf("%c>%c\n", min, max); 
  48.       }
  49.       if (n == bV)
  50.         break;
  51.     }
  52.     while(true);
  53.   }
  54.   else
  55.     cout<<"Impossible";
* This source code was highlighted with Source Code Highlighter.