§ 12. Пошук элементаў з зададзенымі ўласцівасцямі

12.4. Рашэнне задач з выкарыстаннем алгарытма лінейнага пошуку

Прыклад 12.8. На складзе захоўваюцца пустыя скрыні для ўпакоўвання тавару. Вядома, што ёмістасць аднаго пакета з цукеркамі x кг. Вызначыце сумарную масу пакетаў з цукеркамі, якія можна ўпакаваць у такія скрыні, запоўніўшы скрыню цалкам.

Этапы выканання задання

I. Зыходныя даныя: масіў а, колькасць лікаў n, лік x.

II. Вынік: колькасць скрынь — k, сумарная маса — s.

III. Алгарытм рашэння задачы.

1. Увод зыходных даных.
2. Ініцыялізацыя лічыльніка і значэння сумы
:
k = 0; s = 0;
3. Праглядаючы масіў, праверым, ці з’яўляецца бягучы элемент лікам, кратным x (у гэтым выпадку скрыня будзе запоўнена цалкам). Калі кратны, то  павялічым лічыльнік k на 1, а пераменную s — на значэнне знойдзенага элемента масіву
.
4. 
 Вывад выніку.

IV. Апісанне пераменных: n, x, k — int, a – vector <int>.

Прыклад 12.9. Маецца спіс хлопчыкаў 10 «В» класа і вынікі іх бегу на 100 м. Для здачы нарматыву неабходна прабегчы дыстанцыю не больш чым за 16 с. Вывесці прозвішчы навучэнцаў, якія не выканалі нарматыў па бегу. Колькі такіх навучэнцаў у класе? Зыходныя даныя захоўваюцца ў тэкставым файле input.txt. Вынік вывесці ў тэкставы файл output.txt.

Этапы выканання задання

I. Зыходныя даныя: масівы fam (прозвішчы навучэнцаў) і r (вынікі бегу ў секундах), колькасць навучэнцаў n.

II. Вынік: прозвішчы тых навучэнцаў, якія не выканалі нарматыў па бегу.

III. Алгарытм рашэння задачы.

1. Увод зыходных даных.
2. Ініцыялізацыя лічыльніка
: k = 0;
3. Будзем праглядаць масіў з вынікамі і правяраць, ці з’яўляецца бягучы элемент лікам, большым за 16 (нарматыў не здадзены). Калі такое значэнне знойдзена, то выведзем элемент масіву fam з адпаведным нумарам і павялічым значэнне лічыльніка на 1.
.
4. Вывад значэння лічыльніка
.

IV. Апісанне пераменных:  
n, k – int, r – vector <double>,
fam – vector <string>.

Прыклад 12.10. У двух лінейных масівах x і y, зададзеных выпадковым чынам, захоўваюцца каардынаты пунктаў плоскасці (–200 ≤ x[i], y[i] ≤ 200). Вызначыць, якіх пунктаў больш — якія ляжаць унутры або звонку вобласці, абмежаванай акружнасцю радыуса r з цэнтрам у пачатку каардынат (будзем лічыць, што пункты, якія ляжаць на акружнасці, ляжаць унутры вобласці).

Этапы выканання задання

I. Зыходныя даныя: x, y — масівы лікаў, r — радыус акружнасці, n — колькасць пунктаў.

II. Вынік — адно з паведамленняў: «унутры пунктаў больш», «звонку пунктаў больш» або «пунктаў пароўну».

III. Алгарытм рашэння задачы.

1. Увод зыходных даных. 
2. Ініцыялізацыя лічыльнікаў: k1 = 0; k2 = 0; 
3. Будзем праглядаць усе пункты і для кожнага правяраць прыналежнасць вобласці. Калі x2 + y2 R2, то пункт ляжыць унутры вобласці, тады павялічым значэнне лічыльніка k1 на 1, калі не, то павялічым на 1 значэнне лічыльніка k2
4. Параўнаем значэнні k1 і k2 і выведзем вынік.

IV. Апісанне пераменных: n, k1, k2 — int, x, y – vector <int>.

Прыклад 12.11. Зададзены аднамерны масіў з n цэлых лікаў. Вызначыць колькасці элементаў, якія з’яўляюцца лікамі Сміта. Вывесці тыя элементы, якія з’яўляюцца лікамі Сміта. (Лік Сміта — такі састаўны лік, сумма лічбаў якога роўна суме лічбаў усіх яго простых сумножнікаў.) Напрыклад, лікам Сміта з’яўляецца 202 = 2  × 101, паколькі 2 + 0 + 2 = 4 і 2 + 1 + 0 + 1 = 4.

Этапы выканання задання

I. Зыходныя даныя: а — масіў лікаў, n — колькасць лікаў у масіве.

II. Вынік: лікі Сміта і іх колькасць у масіве.

III. Алгарытм рашэння задачы.

1. Увод зыходных даных.
2. Ініцыялізацыя лічыльніка
: k = 0;
3. Будзем праглядаць кожны элемент масіву і вызначаць, ці з’яўляецца ён лікам Сміта. Для праверкі створым функцыю check, якая будзе атрымліваць у якасці параметра элемент масіву, а таксама вяртаць значэнне true, калі лік з’яўляецца лікам Сміта, і false — у адваротным выпадку.

3.1. Знойдзем суму лічбаў ліку.
3.2. Будзем раскладаць лік на простыя множнікі і для кожнага множніка знаходзіць суму лічбаў.
3.3. Для раскладання ліку на простыя множнікі будзем дзяліць яго спачатку  на 2 (пакуль дзеліцца), затым на 3. На 4 лік ужо дзяліцца не будзе, будзем дзяліць на 5 і г. д. Скончыцца раскладанне тады, калі пасля ўсіх дзяленняў лік стане роўным 1.
4. Таксама нам спатрэбіцца функцыя sum, якая для ліку будзе вяртаць яго суму лічбаў. 

IV. Апісанне пераменных:
n, k – int, a – vector <int>.

Прыклад 12.12. Зададзены аднамерны масіў з n радкоў. Даныя ў масіве чытаюцца з тэкставага файла input.txt. Кожны радок з’яўляецца сказам са слоў, падзеленых прабеламі. Знайсці і вывесці ў тэкставы файл output.txt тыя сказы, у якіх няцотная колькасць слоў. Колькі сказаў вывелі?

Этапы выканання задання

I. Зыходныя даныя: а — масіў лікаў, n — колькасць лікаў у масіве.

II. Вынік: шуканыя радкі і іх колькасць.

III. Алгарытм рашэння задачы.

1. Увод зыходных даных.
2. Ініцыялізацыя лічыльніка
: k = 0;
3. 
Будзем праглядаць кожны радок і вызначаць, колькі ў ім слоў. Для праверкі створым функцыю check, якая будзе атрымліваць у якасці параметра элемент масіву і вяртаць колькасць слоў у радку. Калі колькасць слоў з’яўляецца няцотным лікам, то выведзем радок і павялічым значэнне лічыльніка.

3.1. Перад кожным словам сказа, акрамя першага, стаіць прабел. Слова пачынаецца з сімвала, які прабелам не з’яўляецца.
3.2. Дабавім прабел перад першым словам, тады колькасць слоў будзе вызначацца колькасцю спалучэнняў пар сімвалаў: прабел і не прабел.

IV. Апісанне пераменных:
n, k – int, а – vector <string>
.

Прыклад 12.8.

V. Праграма:

#include <iostream>

#include <vector>

 

using namespace std;

 

int main()

{

  setlocale(0,"");

  int n;

  cout << "n = ";

  cin >> n;

  vector <int> a(n);

  for (int i = 0; i < n; i++)

    cin >> a[i];

  int x;

  cout << "маса цукерак ";

  cin >> x;

  int s = 0, k = 0;

  for (int i = 0; i < n; i++)

    if (a[i] % x == 0){

      k++;

      s += a[i];

    }

  cout << "упакавалі " << k;

  cout << " скрынь, сумарная маса ";

  cout << s << " кг" << endl;

  return 0;

}

VI. Тэсціраванне.

VII. Аналіз вынікаў. Скрыні, якія задавальняюць умову задачы, маюць масу 15, 25, 10, 20, 45.

Прыклад 12.9.

V. Праграма:

#include <iostream>

#include <fstream>

#include <vector>

#include <string>

 

using namespace std;

 

int main()

{

  ifstream fin ("input.txt");

  ofstream fout ("output.txt");

  int n;

  fin >> n;

  fin.ignore (); 

  vector <string> fam(n);

  vector <double> r(n);

  for (int i = 0; i < n; i++)

    fin >> fam[i] >> r[i];

  int k = 0;

  for (int i = 0; i < n; i++)

    if (r[i] > 16){

      fout << fam[i] << endl;

      ++;

    }

  fout << "не здалі нарматыў ";

  fout << k << навучэнцаў" << endl;

  return 0;

}

VI. Тэсціраванне.

VII. Аналіз вынікаў. Вынік Сідарава 21, а Каралёва 16.1, што перавышае нарматыў.

Прыклад 12.10.

V. Праграма:

#include <iostream>

#include <vector>

#include <ctime>

#include <cstdio>

 

using namespace std;

 

int main()

{

  srand(time(NULL));

  int n, r;

  cout << "n = ";

  cin >> n;

  cout << "r = ";

  cin >> r;

  vector <int> x(n), y(n);

  for (int i = 0; i < n; i++){

    x[i] = rand() % 401 - 200;

    y[i] = rand() % 401 - 200;

  }

  int k1 = 0, k2 = 0;

  for (int i = 0; i < n; i++)

    if (x[i] * x[i] + y[i] * y[i] 
        
<= r * r)

      k1++;

    else

      k2++;

  if (k1 > k2)

    cout << "vnutri";

  else

    if (k1 < k2)

      cout << "snarugi";

    else

      cout << "porovnu";

  cout << endl;

  return 0;

}

VI. Тэсціраванне.

VII. Аналіз вынікаў. Паводле паведамленняў, якія выдае праграма, складана меркаваць пра яе правільнасць. Для праверкі можна вывесці значэнні каардынат кожнага пункта ў файл і пры праверцы ставіць дадатковыя паметкі. Напрыклад, «+», калі пункт унутры, і «-», калі звонку.

Прыклад 12.11.

V. Праграма:

#include <iostream>

#include <vector>

 

using namespace std;

 

int sum(int x)

{

  int s = 0;

  while (>0){

    s += x % 10;

    x /= 10;

  }

  return s;

}

 

bool check(int x)

{

  int s1 = sum(x);

  int s2 = 0;

  int d = 2;

  //разкладанне на простыя множнікі

  while (!= 1){

    while (% d == 0){

      s2 += sum(d);

      x /= d;

    }

    d++;

  }

  return (s1 == s2);

}

 

int main()

{

  int n;

  cout << "n = ";

  cin >> n;

  vector <int> a(n);

  for (int i = 0; i < n; i++)

    cin >> a[i];

  int k = 0;

  for (int i = 0; i < n; i++)

    if (check(a[i])){

      k++;

      cout << a[i] << " ";

  }

  cout << endl << "vsego " << k;

  cout << " chisel Smita" << endl;

  return 0;

}

VI. Тэсціраванне.

Прыклад 12.12.

V. Праграма:

#include <iostream>

#include <fstream>

#include <vector>

#include <string>

#include <windows.h>

 

using namespace std;

using namespace std::__cxx11;

 

int check(string x)

{

  int k = 0;

  x = " " + x;

  int len = x.length();

  for (int i = 0; i < len - 1; i++)

    if (x[i] == ' ' && x[+ 1] != ' ')

      k++;

  return k;

}

 

int main()

{

  SetConsoleCP(1251);

  SetConsoleOutputCP(1251);

  ifstream fin("input.txt");

  ofstream fout("output.txt");

  int n;

  fin >> n;

  fin.ignore();

  vector <string> a(n);

  for (int i = 0; i < n; i++)

    getline(fin, a[i]);

  int k = 0;

  for (int i = 0; i < n; i++)

    if (check(a[i]) % 2){

      fout << a[i] << endl;

      k++;

    }

  fout << "Всего - " << k;

  fout << строк(–а, –u)" << endl;

  return 0;

}

VI. Тэсціраванне.