БлогNot. 14 не пригодившихся задач за январь 2021

14 не пригодившихся задач за январь 2021

Очень давно здесь не было "не пригодившихся задач", кажется, ещё вот откуда.

Ну, не занимался как-то с тех пор этим :)

Все задачи проверялись в консоли актуальной сборки Visual Studio 2019, для быстрого поиска на странице нужного слова нажимайте комбинацию клавиш Ctrl+F в браузере. Большинство кодиков использует контейнеры STL.

1. Найти и вывести все последовательности возрастающих элементов массива.

#include <iostream>
#include <vector>
 
int main() {
 const int n = 10;
 std::vector <double> a(n);
 for (std::size_t i = 0; i < n; i++) {
  std::cin >> a[i];
 }
 std::size_t start = 0, end = 0;
 for (std::size_t i = 0; i < n-1; i++) {
  if (a[i] < a[i+1]) end++; //знак "<=", если нужно неубывание, а не возрастание
  else {
   if (start < end) {
    std::cout << std::endl;
    for (std::size_t k = start; k<=end; k++) std::cout << a[k] << " ";
   }
   if (i < n - 1) {
    start = end + 1;
    end = start;
   }
  }
 }
 if (start < end) {
  std::cout << std::endl;
  for (std::size_t k = start; k <= end; k++) std::cout << a[k] << " ";
 }
}

2. Дано целое n. Найти сумму n2 + (n+1)2 + ... + (2*n)2

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

int main() {
 int n;
 double s = 0;
 cout << "N=";
 cin >> n;
 for (int i = 0; i <= n; i++) s += pow(n+i,2);
 cout << s;
 return 0;
}

3. Написать программу, которая вычисляет среднюю оценку (оценки - это значения от 1 до 10 включительно) и определяет, сколько из введенных оценок не удовлетворительны (меньше 4).

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

int main() {
 int n;
 cout << "Введите количество оценок: ";
 cin >> n;
 if (!cin.good() || n < 2) {
  cout << "Требуется хотя бы 2 оценки";
  return 1;
 }
 int a, k = 0;
 double s = 0;
 for (int i = 1; i <= n; i++) {
  cout << i << " оценка: ";
  cin >> a;
  if (!cin.good() || a < 1 || a > 10) {
   cout << "Требуется оценка от 1 до 10";
   return 2;
  }
  if (a < 4) k++;
  s += a;
 }
 s /= n;
 cout.precision(2);
 cout << "Среднее значение успеваемости: " << s  << endl;
 cout << "Всего неудовлетворительных оценок: " << k;
 return 0;
}

4. Написать функцию, где вычисляется выражение f(x). Код функции реализовать с помощью условных операторов if (конкретная функция - расчёт по трём ветвям алгоритма).

Написать код, в котором:

  • объявить две переменные вещественного типа x и y;
  • осуществить ввод значения для переменной х с приглашением (вид приглашения сформулировать самостоятельно);
  • применить функцию f(x), которая возвращает значение в переменную y;
  • осуществить вывод значения переменной у с комментарием (вид комментария сформулировать самостоятельно).

Вот такая излишне подробная формулировка задания :)

#include <iostream>
#include <cmath>
using namespace std;
 
double f(double x) {
 if (x <= -2) return pow(x,3)+2;
 else if (x<3) return 1/sqrt(2)*sin(x/2);
 return log10(2*x);
}
 
int main() {
 int n;
 double x, y;
 cout << "X=";
 cin >> x;
 y = f(x);
 cout << "Y=" << y;
 return 0;
}

5. С помощью цикла с параметром for вычисляются значения y функции f(x) из предыдущей задачи на заданном интервале [x1, x2] с заданным шагом dx. Значения для границ интервала x1, x2 и шага dx задать с клавиатуры. На каждой итерации цикла выводить значения x, y.

В этом же цикле for вычислять максимальное и минимальное значения y.

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

double f(double x) {
 if (x <= -2) return pow(x, 3) + 2;
 else if (x < 3) return 1 / sqrt(2) * sin(x / 2);
 return log10(2 * x);
}

int main() {
 int n;
 double x1, x2, dx, y;
 cout << "x1=";
 cin >> x1;
 cout << "x2=";
 cin >> x2;
 cout << "dx=";
 cin >> dx;
 cout.precision (2);
 cout << setw(10) << "X" << setw(10) << "Y";
 double miny = f(x1), maxy = miny;
 for (double x = x1; x <= x2; x += dx) {
  y = f(x);
  cout << endl << setw(10) << x << setw(10) << y;
  if (y > maxy) maxy = y;
  if (y < miny) miny = y;
 }
 cout << endl << "minY=" << miny;
 cout << endl << "maxY=" << maxy;
 return 0;
} 

Проверки корректности ввода тут нет.

x1=-3
x2=3
dx=0.5
         X         Y
        -3       -25
      -2.5       -14
        -2        -6
      -1.5     -0.48
        -1     -0.34
      -0.5     -0.17
         0         0
       0.5      0.17
         1      0.34
       1.5      0.48
         2       0.6
       2.5      0.67
         3      0.78
minY=-25
maxY=0.78

6. Разложение синуса в ряд для значения x, точность 14 знаков в дробной части, выход - когда очередной член ряда станет меньше eps.

Не стоит пытаться вычислить этим кодом синус от аргумента, равного 50 или 100 радианов, так там сходимости по определению не будет.

Формула Маклорена, вообще говоря, работает только при аргументе, по модулю меньшем 1.

Реальный синус от IBM... Как видно, тема на самом деле далеко не проста!

#include <iostream>
#include <iomanip> 
#define _USE_MATH_DEFINES
#include <math.h>

double sin_(double x, double eps) { 
 double s = 0, nf = 1, x1 = x, x2 = pow(x,2), item;
 int i = 1, sign = 1;
 do {
  item = x1 / nf;
  s += (sign > 0 ? item : -item);
  sign = - sign;
  x1 *= x2;
  nf *= ((double)i + 1) * ((double)i + 2);
  i += 2;
 } while (abs(item) >= eps);
 return s; 
}

int main() {
 double x = M_PI / 4, eps = 1e-14;
 std::cout.precision (14);
 std::cout << "My function: " << sin_(x,eps) << std::endl <<
  "Standard function: " << sin(x);
 return 0;
}

7. В американской армии считается несчастливым число 13, а в японской — 4. Перед международными учениями штаб российской армии решил исключить номера боевой техники, содержащие числа 4 или 13 (например, 40123, 13313, 12345 или 13040), чтобы не смущать иностранных коллег. Если в распоряжении армии имеется 100 тыс. единиц боевой техники и каждая боевая машина имеет номер от 00001 до 99999, то сколько всего номеров придётся исключить?

#include <iostream>
using namespace std;

int main () {
 int A; //цифры
 int n = 0; //счетчик "особых номеров"
 for (int a = 3; a < 100000; a++) {
  A = a;
  while (A >= 4) {
   if (A % 10 == 4 || A % 100 == 13) {
    cout << a << " ";
    ++n;
    break;
   }
   A /= 10;
  }
 }
 cout << endl << "Count = " << n;
 return 0;
}

8. Простое "цезареподобное" шифрование и дешифрование нужных символов.

#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <random>
using namespace std;

string convert(string& s, int key, bool encoding) {
 //строка, случайный ключ, кодируем (true) или декодируем (false)
 char char_set[] = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
  //шифруемые символы
 unsigned char_set_length = strlen(char_set);
 key %= char_set_length; 
 auto get_char_pos = [char_set, char_set_length](char c) -> unsigned {
  auto found = find(char_set, char_set + char_set_length, c);
  return found != char_set + char_set_length ? found - char_set : char_set_length;
 };
 transform(s.begin(), s.end(), s.begin(), [key, char_set, char_set_length, &get_char_pos, encoding](char c) {
  auto original_pos = get_char_pos(c);
  if (original_pos == char_set_length) return c;
  return char_set[(original_pos + (encoding ? key : char_set_length - key)) % char_set_length];
  });
 return s;
}

string encode(string s, int& key) {
 key = 0;
 if (s.empty()) return s;
 mt19937 gen(random_device{}());
 uniform_int_distribution<> dist(1, 100);
 key = dist(gen);
 return convert(s, key, true);
}

string decode(string s, int key) {
 if (s.empty()) return s;
 return convert(s, key, false);
}

int main() {
 string s = "This is the original text, digits are not encoded 0123456789";
 int key;
 cout << "Encoded: " << (s = encode(s, key)) << endl;
 cout << "key = " << key << endl;
 cout << "Decoded: " << decode(s, key) << endl;

 return 0;
}

9. Написать функцию которая принимает вектор целых чисел(все числа состоят из одной цифры) и прибавляет к последнему числу единицу. Если число становится равно 10, то в ячейку записывается 0, а единица прибавляется к предпоследнему числу и т.д., например:

input: [1, 2, 3, 9, 9]
output: [1, 2, 4, 0, 0]

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

void add_one_recursively(vector<short>& v, unsigned i) {
 if (i >= v.size()) { v.push_back(1); return; }
 if (v[i] < 9) ++v[i];
 else {
  v[i] = 0;
  add_one_recursively(v, i + 1);
 }
}

void add_one(vector<short>& v) {
 if (v.empty()) return;
 reverse(v.begin(), v.end());
 add_one_recursively(v, 0);
 reverse(v.begin(), v.end());
}

int main(){
 vector<short> v { 1, 2, 3, 9, 9 };
 add_one (v);
 for (auto e : v) cout << e << " ";
 cout << endl;
 return 0;
}

10. Найти разность двух символьных множеств.

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
 set <char> firstSet{ 'h', 'e', 'l', 'l', 'o' };
 set <char> secondSet{ 'w', 'o', 'r','l','d' };
 set <char> res;
 set<char>::iterator it;

 set_difference(firstSet.begin(), firstSet.end(), 
  secondSet.begin(), secondSet.end(), inserter(res, res.end()));
 for (it = res.begin(); it != res.end(); ++it) {
  cout << *it << " ";
 }
 return 0;
}

11. Из контейнера структур типа struct n2 { int a,b; } удалить все элементы, для которых a не делится нацело на b.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct n2 {
 int a;
 int b;
};

bool check (n2 smth) { return smth.a % smth.b; }

int main() {
 vector <n2> vec{ {1,2}, {5,6}, {8,11}, {16,8}, {5,5} };
 vec.erase(remove_if(vec.begin(), vec.end(), check), vec.end());
 for (vector<n2>::iterator i = vec.begin(); i != vec.end(); ++i) {
  cout << i->a << " " << i->b << endl;
 }
 return 0;
}

12. Дан вектор V. Определить количество повторений каждого числа в векторе V и вывести все различные элементы вектора V вместе с количеством их повторений (в порядке возрастания значений элементов); количество повторений выводить сразу после значения соответствующего элемента.

Решить задачу, не используя функцию upper_bound и цикл. Вместо этого использовать вспомогательное мультимножество M и вспомогательное множество S (создав их на основе исходного вектора) и алгоритм for_each для множества S с параметром — функциональным объектом, в котором использовать функцию-член count мультимножества M.

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;

multiset <int> M;

int main() {
 vector <int> V{ 6,7,5,4,3,2,1,2,6,4,3,2 };
 sort(V.begin(), V.end());

 set <int> S;
 for (vector<int>::iterator i = V.begin(); i != V.end(); ++i) {
  M.insert(*i);
  S.insert(*i);
 }
 for_each(S.begin(), S.end(), 
  [](int n) { cout << n << " | " << M.count(n) << endl; }
 );
 return 0;
}

13. Дан вектор V. Выполнить группировку элементов вектора V, используя в качестве ключа группировки последнюю (т. е. правую) цифру элемента: в одну группу должны входить все элементы вектора V, оканчивающиеся на одну и ту же цифру (сгруппированные элементы должны располагаться в том же порядке, в котором они располагались в исходном векторе). Представить результат группировки в виде мультиотображения M (класса multimap), ключами которого являются ключи группировки, т. е. последние цифры элементов вектора V, а значениями — элементы вектора, оканчивающиеся на соответствующую цифру (таким образом, отображение M должно иметь тип multimap). Вывести полученное отображение (для каждого элемента отображения M вначале выводить ключ, а затем связанный с ним элемент вектора V; ключи могут повторяться). Для перебора элементов контейнеров использовать циклы с параметрами-итераторами.

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

multimap <int, int> M;

int main() {
 vector<int> V{ 123,533,234,1598, 444,13 };

 for (vector<int>::iterator i = V.begin(); i != V.end(); ++i) {
  int key = (*i % 10);
  if (M.find(key) == M.cend()) {
   for (vector<int>::iterator j = V.begin(); j != V.end(); ++j) {
    if (key == (*j % 10)) {
     M.insert(pair<int, int>(key, *j));
    }
   }
  }
 }
 for (multimap <int, int>::iterator i = M.begin(); i != M.end(); ++i) {
  cout << i->first << " | " << i->second << endl;
 }
 return 0;
}


14. Дан вектор V, содержащий не менее трех различных чисел. Вывести все его различные элементы, кроме максимального и минимального, в порядке убывания.

Решить задачу, не используя вспомогательное множество. Вместо него последовательно использовать для исходного вектора алгоритмы sort, unique и copy.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
 setlocale(LC_ALL, "rus");
 vector <double> vectors;
 int amount;
 double value;
 cout << "Введите количество элементов вектора: ";
 cin >> amount;

 for (int i = 0; i < amount; i++) {
  cout << "vectors[" << i << "]: ";
  cin >> value;
  vectors.push_back(value);
 }
 sort(vectors.begin(), vectors.end(), greater<double>());
 auto last = unique(vectors.begin(), vectors.end());
 vectors.erase(last, vectors.end());
 for (int i = 1; i < vectors.size() - 1; i++) {
  cout << "v[" << i << "]: " << vectors[i] << endl;
 }
 return 0;
}

16.01.2021, 16:08 [1513 просмотров]


теги: учебное список c++ алгоритм

К этой статье пока нет комментариев, Ваш будет первым