Консультация № 145975
04.10.2008, 15:36
0.00 руб.
0 10 1
Здравствуйте, помогите пожалуста решить след. задачи и отладить или решить заново задачу в приложении:
4. Вроде всё правильно, но глючит. см. приложение.
5. Задана матрица A(n,m), упорядоченная по возрастанию построкам и столбцам, то есть
A(i,1)<=A(i,2)<=...<=A(i,m), для любого i
A(1,j)<=A(2,j)<=...<=A(n,j), для любого j
6. Даны 2 целочисл. таблицы A(10) и B(15). Разработать алгоритм и написать программу, которая проверяет,
являются ли эти таблицы похожими. 2 таблицы будем называть похожими, если совпадают множества чисел,
встречающихся в этих таблицах.
PS: все задачи на тему "Сложность и эффективность алгоритмов. Поиск и сортировка информации", нумеровка
как в списке задач.

Приложение:
//Дан набор монет, и ещё одна монета (эталон). Есть ли в наборе монета, равная
//по весу эталону?

//Я так понимаю, может и неправильно ;), что в наборе все монеты одинаковые по весу, и если в нем
//присутствует эталон, то только один.

#include <iostream>
#include <conio.h>
#include <deque>
using namespace std;

int ves (int begin, int end, deque<int> c) {
int sum;
for ( ; begin <= end; begin++) sum += c[begin];
return sum;
};

int ifetaloninmassiv (int left, int right, deque<int> c, int metalon) {
int etalon2 = -1;
cout << c.size (); //для контроля цикла
if ((right-left+1)%2==1) {
if (c[right] != metalon) right--;
else { etalon2 = right; return etalon2; };
};
int mleft, mright;
mleft = ves (left, left+(right-left)/2, c);
mright = ves (left+(right-left)/2+1, right, c);
if (mleft == mright) return etalon2 = -1;
else {
int first, last;
first = ifetaloninmassiv (left, right/2, c, metalon);
if (first != -1) return first;
last = ifetaloninmassiv (right/2+1, right, c, metalon);
return last;
};
};

int main () {
deque<int> c;
int metalon, chislo;
int etalon2;
cout << "enter veight of etalon\n";
cin >> metalon;
cout << "enter veight of coin or -1 to end\n";
cin >> chislo;
c.push_back (chislo);
while (c.back () != -1) {
cin >> chislo;
c.push_back (chislo);
};
c.pop_back ();
etalon2 = ifetaloninmassiv (0, c.size (), c, metalon);
if (etalon2 != -1) cout << "yes, there is second etalon in massiv at the position " << etalon2;
else cout << "there is no second etalon in massiv";
getch ();
return 0;
}

Обсуждение

Неизвестный
04.10.2008, 20:24
общий
это ответ
Здравствуйте, Piotr-1!

4. Если у вас список монет сортированый - то ищите эталон двоичным или троичным поиском, более быстрый алгоритм довольно сложно придумать. А на несортированные списки быстрый поиск вообще не распространяется - ищите перебором.

5. Вопрос так и не задали...

6. Если таблицы не сортированы - берём первое число в B, удаляем из B все его вхождения, удаляем из A все его вхождения, если из А ничего удалено не было - значит списки не похожи. Если B пустой, а A - нет, значит списки не похожи.
Неизвестный
05.10.2008, 17:52
общий
Если я правильно понял пункт 4., то вот одно из возможных решений:
Код:
//Дан набор монет, и ещё одна монета (эталон). Есть ли в наборе монета, равная
//по весу эталону?

//Я так понимаю, может и неправильно ;), что в наборе все монеты одинаковые по весу, и если в нем
//присутствует эталон, то только один.

#include <iostream> // cin, cout
#include <vector> // vector<>
#include <algorithm> // copy(), find()
#include <iterator> // istream_iterator<>, distance()
#include <conio.h> // getch()

using namespace std;

typedef vector<int> IntV;

int main ()
{
IntV c;
int metalon;
cout << "Enter weight of etalon\n"; cin >> metalon;

cout << "Enter weight of coin or -1 to end\n";

// тип unsigned взят специально,
// когда пользователь введет отрицательное число
// или любой символ, ввод прекратится
copy(istream_iterator<unsigned>(cin), istream_iterator<unsigned>(),
back_inserter(c));

// Поиск этанола в массиве
IntV::iterator etalon2(find(c.begin(), c.end(), metalon));

// если найден
if (etalon2 != c.end())
{
// ищем еще один
if (find(etalon2+1, c.end(), metalon) == c.end())
// найден только один
cout << "Yes, there is the second etalon in the array at position " << distance(c.begin(), etalon2);
else
// найдено два
cout << "There are more than two etalons in the array";
}
else
// не найдено ни одного
cout << "There is no more etalons in the array";
cout << endl;

getch();

return 0;
}
deque был заменен на vector. deque - это двусторонние очереди, но в Вашем случае она используется как односторонняя очередь (используете только push_back()), а в качестве односторонней очереди (ИМХО) лучше использовать обычный вектор. Ну и для поиска, по-моему, лучше использовать стандартные алгоритмы (модуль <algorithm>), если не указано, что поиск нужно реализовать самостоятельно.
Неизвестный
05.10.2008, 18:25
общий
Странно Отправили бы как ответ, он бы хоть в рассылку попал...
Неизвестный
07.10.2008, 12:37
общий
5. Конец условия задачи (так торопился, что забыл дописать):
Найти элемент матрицы, равный заданному числу X и отпечатаь его индексы.
Напечатать "такого элемента нет", если такого элемента в массиве не окажется.
Х можно сравнивать не более, чем с N+M элементами матрицы.

4. (пояснение) Монеты взвешиваются на рычажных весах. Полный перебор не использовать.
Неизвестный
07.10.2008, 22:23
общий
А нельзя ли, в таком случае, полностью задачу 4 сформулировать (как указано в задании). А то что-то до меня не доходит ее смысл.
Неизвестный
08.10.2008, 22:23
общий
Дан набор монет и ещё одна монета (назовём её эталоном). Есть ли в наборе монета, равная по весу эталону? Монеты взвешиваются на рычажных весах. Полный перебор не использовать.
//вот и всё условие задачи. Больше ничего не знаю
Неизвестный
08.10.2008, 22:41
общий
Кстати, решил 6 задачу:
#include <iostream>
#include <list>
#include <fstream>
using namespace std;

int main ()
{
const int n = 10, m = 15;
list<int> a(n), b(m);
list<int>::iterator i;
ifstream inp ("input.txt");
ofstream outp ("output.txt");
for (i = a.begin (); i != a.end (); ++i) inp >> *i;
for (i = b.begin (); i != b.end (); ++i) inp >> *i;
a.sort (); b.sort ();
a.unique (); b.unique ();
if (a.size () != b.size ()) outp << "Tables are not similar";
else {
for (i = a.begin (); i != a.end (); ++i) b.remove (*i);
if (b.size () == 0) outp << "Tables are similar";
else outp << "Tables are not similar";
};
return 0;
}

4 и 5 же задачи у меня никак не получается решить. Помогите, пожалуйста,
срочно решить их к вечеру пятницы...
Неизвестный
10.10.2008, 22:01
общий
пожалуйста, скажите почему в строке, помеченной коментарием, ошибка (Dev-C++4.9) ????!!!!!!
//Дан набор монет, и ещё одна монета (эталон). Есть ли в наборе монета, равная
//по весу эталону? монеты взвешиваются на рычажных весах. Полный перебор не использовать.
//Предположим, что в наборе все монеты одинаковые по весу, и если в нем
//присутствует эталон, то только один.
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int ves (int begin, int end, vector<int> c) {
int sum;
for ( ; begin <= end; begin++) sum += c[begin];
return sum;
};

bool reshenie (int l, int r, vector<int> c, int metalon) {
int m;
if ( (r-l)%2 == 1 ) {
if (metalon == c[r]) return true;
else r--;
};
m = (r-l)/2;
if ( ves (l, m, c) == ves (m+1, r, c) ) return false;
else return reshenie (l, m, c, metalon) || reshenie (m+1, r, c, metalon);
};

int main () {
vector<int> c[100];
int metalon, n, i;
ofstream outp ("output.txt");
ifstream inp ("input.txt");
inp >> metalon;
inp >> n;
for (i = 0; i < n; i++) inp >> c[i]; //ошибка 34 no match for 'operator>>' in 'inp >> c[i]'
if (reshenie (0, n, c, metalon) ) outp << "there is second etalon in array";
else outp << "there isn't second etalon in array";
return 0;
}

ЗЫ: 5я задача решена
Неизвестный
11.10.2008, 18:05
общий
Интересно, решит ли кто-нибудь задачу №4.....
Неизвестный
11.10.2008, 22:24
общий
Если задача выглядит так: "дано n-1 монеток одинакового веса и 2 монетки другого веса. Одну из этих двух монеток добавили к набору, вторая осталась в нашем распоряжении. Найти в наборе монетку - эталон" то можно искать примерно так:

1. Сравниваем случайную монетку из набора и эталон. Если они равны - случилось чудо (В общем, конец алгоритма). Если эталон больше весит - $T = "большая", если меньше - $T = "меньшая".

A:

2. Если в наборе осталась одна монетка - сравниваем её с эталоном и сообщаем о результате (конец алгоритма).
3. Делим набор монеток на три части. Две из них равны количественно, третья - произвольна (оптимальнее всего, когда все три части примерно равны)
4. Взвешиваем первые две части набора. Если они равны - убираем их из дальнейшего рассмотрения и идём к пункту A. Если среди них есть $T по весу - убираем
из набора всё, кроме этой части и идём к пункту A.

Вот, собственно, и был троичный поиск.
Форма ответа