Консультация № 185494
24.02.2012, 13:29
0.00 руб.
26.02.2012, 20:09
0 95 5
Уважаемые эксперты! Пожалуйста, помогите решить задачи из Задачника М. Э. Абрамяна , раздел Array.

Array6. Даны целые числа N>2, A и B. Сформировать и вывести целочисленный массив размера N, первый элемент которого равен A, второй равен B, а каждый последующий элемент равен сумме всех предыдущих.

Array10. Дан целочисленный массив размера N. Вывести вначале все содержащиеся в данном массиве четные числа в порядке возрастания их индексов, а затем — все нечетные числа в порядке убывания их индексов.

Array18. Дан массив A ненулевых целых чисел размера 10. Вывести значение первого из тех его элементов AK, которые удовлетворяют неравенству A[K] < A[10]. Если таких элементов нет, то вывести 0.

Array49. Дан целочисленный массив размера N. Если он является перестановкой, т. е. содержит все числа от 1 до N, то вывести 0; в противном случае вывести номер первого недопустимого элемента.

Спасибо.

Обсуждение

давно
Старший Модератор
31795
6196
29.02.2012, 13:44
общий
Смотрите на рисунок:
В красных квадратах обведены выражения k=++i и k=i++. (var_4 и var_8 это i в циклах, var_C это k).
Я думал, что компилятор в случае с прединкрементом поставит выделенный код сразу после метки loc_401338:
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
29.02.2012, 14:15
общий
Адресаты:
По определению for выражение вычисляется в конце цикла. Поэтому следующие записи эквивалентны:
Код:
for (int k = 0; k < n; ++k)

Код:
for (int k = 0; k < n; k++)

Большинство компиляторов сгенерирует для них одинаковый машинный код в релизной версии.
давно
Старший Модератор
31795
6196
29.02.2012, 14:44
общий

А, я так надеялся.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Академик
320937
2216
29.02.2012, 15:45
общий
29.02.2012, 15:46
Наш совместный проект :)
Код:
/*----------------------------------------------------------Задание----------------------------------------------------------------
Array49. Дан целочисленный массив размера N. Если он является перестановкой,
т. е. содержит все числа от 1 до N, то вывести 0;
в противном случае вывести номер первого недопустимого элемента.
Гусятинер Л.Б. && Маслаков А.Ю., КККМТ
-----------------------------------------------------------------------------------------------------------------------------------*/
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
system ("chcp 1251>nul");
int n;
cout<<"введите размерность массива - ";
cin>>n;
vector<int> v1;
for (vector<int>::size_type i=0; i!=n ;i++)
{
int y;
cin >> y;
v1.push_back(y);
}

bool x=true;
vector<int> v2(n,1);
vector<int>::size_type k=0;
for (vector<int>::size_type i=0; i!=n && x==true; i++)
{
if (v1[i]-1>=n || v2[v1[i]-1]==0)
{
k=i;
x=false;
}
else
v2[v1[i]-1]=0;
}

if (x==true)
cout<<0<<endl;
else
cout<<k+1<<endl;

return 0;
}

Неизвестный
29.02.2012, 16:48
общий
Адресаты:
Наш совместный проект :)

Что же вы отрицательные числа не уважаете ?
Не работает ваша программа с массивами, где хотя бы одно число меньше единицы.
давно
Академик
320937
2216
29.02.2012, 17:17
общий
До закрытия консультации двое суток. Вы вполне успеете оформить Ваш ответ. И это будет интересно нашим студентам (да и читателям, надеюсь).
давно
Академик
320937
2216
29.02.2012, 18:01
общий
Адресаты:
Вообще-то я предлагал использовать просто size_t во всех случаях. Тогда, кстати, и вопрос об отрицательных числах не возникает.
давно
Академик
320937
2216
29.02.2012, 18:16
общий
29.02.2012, 18:18
Адресаты:
Вы бы не могли для народа дать комментарии к кусочку Вашего кода, Константин Николаевич?
Код:
{
x=false;
l=k;
}
v1.push_back(y);
}
k=0;
while( k<n && x )
{
++l%= n;
x = v1[k]!=v1[l] || k==l;
if( l==0 )
{
l=++k;
}
}
Неизвестный
29.02.2012, 18:27
общий
это ответ
Здравствуйте, lamed!
Задача Array49. Ввод массива одной строкой, разделяя пробелами.
Код:

// Array49. Оптимальное количество итераций
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
string input;
getline(cin, input);
copy(istream_iterator<int>(istringstream(input)), istream_iterator<int>(), back_inserter(v));

vector<int> c(v.size(), 0);
int result = 0;
for (int k = 0; k < v.size(); ++k)
{
if (v[k] < 1 || v[k] > v.size() || c[v[k] - 1] > 0)
{
result = k + 1;
break;
}
++c[v[k] - 1];
}
cout << result << endl;
return 0;
}

Код:

// Array49. Оптимальное использование памяти
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
string input;
getline(cin, input);
copy(istream_iterator<int>(istringstream(input)), istream_iterator<int>(), back_inserter(v));

int result = 0;
for (int k = 0; k < v.size() && result == 0; ++k)
{
if (v[k] < 1 || v[k] > v.size())
{
result = k + 1;
break;
}
for (int j = 0; j < k; ++j)
{
if (v[j] == v[k])
{
result = k + 1;
break;
}
}
}
cout << result << endl;
return 0;
}
Неизвестный
29.02.2012, 18:32
общий
29.02.2012, 18:33
Адресаты:
Выложил свои два варианта Array49
давно
Старший Модератор
31795
6196
29.02.2012, 18:34
общий
29.02.2012, 18:36
Задание сводится к: все числа должны быть от 1 до N и не должны повторятся:

Код:
    for (k=0; k<n ;k++)
{
cin >> y;
if(y<=0 || y>n)//проверка условия числа от 1 до N
{
x=false;//сбрасываем флаг ошибки
l=k;//запоминаем индекс
}
v1.push_back(y);
}
k=0;//сбрасываем индекс
while( k<n && x )//два условия: первое - индекс внешнего цикла, второе флаг ошибки
{
++l%= n;//эта команда при любом приращении индекса внутренео цикла присваивает ему значение 0..N-1
x = v1[k]!=v1[l] || k==l;//проверка на совпадение элементов с исключением проверки с одинаковым индексом
if( l==0 )//индекс внутреннего цикла достиг конца массива(см. выше)
{
l=++k;//увеличиваем индекс внешнего цикла
}
}
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Академик
320937
2216
29.02.2012, 18:37
общий
Адресаты:
Большое спасибо!!
давно
Старший Модератор
31795
6196
29.02.2012, 18:41
общий
Цитата: 321399
Неверно обрабатывается массив [1, 2, 2, 1]

Какая ошибка?

Цитата: 321399
Также мешать ввод с логикой - плохая практика,

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

Цитата: 321399
маскировать двойной цикл - тоже не очень хорошо

я не утверждал, что это хороший тон программирования, но код получается меньше, чем с вложенными циклами.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
29.02.2012, 18:51
общий
Адресаты:
Какая ошибка?

Печается 4 вместо 3.
я не утверждал, что это хороший тон программирования

С нас берут пример дети
давно
Старший Модератор
31795
6196
29.02.2012, 18:58
общий
Цитата: 321399
Печается 4 вместо 3.



Это смотря как проверять.

Цитата: 321399
С нас берут пример дети


Они уже всё умеют.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
29.02.2012, 19:07
общий
Адресаты:
Это смотря как проверять.

Как ни проверяй, вывод неправильный
давно
Старший Модератор
31795
6196
29.02.2012, 19:38
общий
Если Вы считаете, что первой должна быть 1,2,2,1
Тогда снова спасает проверка при вводе, так даже проще:
Код:
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
unsigned n,m;
cout<<"enter size:";
cin>>n;
vector<int> v1;
vector<int>::size_type k,l;
int y;
bool x=true;
for (k=0; k<n ;k++)
{
cin >> y;
if(y<=0 || y>n)//
{
x=false;//
m=k;//
}
v1.push_back(y);
if( x )
{
m=l=k;
while(l>0 && x)
{
x=v1[--l]!=v1[k];
cout <<v1[l]<<" vs "<<v1[k]<<" - "<<l<<":"<<k<<endl;
}
}
}
if ( x )
cout<<0<<endl;
else
cout<<m+1 <<":=" <<v1[m] << endl;
return 0;
}

Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
29.02.2012, 20:03
общий
Адресаты:
Если Вы считаете, что первой должна быть 1,2,2,1

Это не я считаю, так написано в задании: "вывести номер первого недопустимого элемента".
Последний вариант не работает на массиве [1,2,2,6]
давно
Старший Модератор
31795
6196
29.02.2012, 20:09
общий
29.02.2012, 20:21
if(y<=0 || y>n)
Сюда добавить && X
((y<=0 || y>n)&& x)
Тогда не будут проводится остальные проверки, если первый найден.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
29.02.2012, 20:24
общий
Адресаты:
Сюда добавить && X

Согласен, теперь всё верно.
давно
Старший Модератор
31795
6196
29.02.2012, 20:26
общий

Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
29.02.2012, 20:46
общий
Адресаты:
Код:
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
unsigned n;
cout<<"enter size:";
cin>>n;
vector<int> v1;
vector<int>::size_type k,l;
int y;
bool x=true;
for (k=0; k<n ;k++)
{
cin >> y;
v1.push_back(y);
if( x )
{
x=(y>0 && y<=n);
l=k;
while(l>0 && x)
x=v1[--l]!=v1[k];
l=k;
}
}
if ( x )
cout<<0<<endl;
else
cout<<l+1 <<":=" <<v1[l] << endl;
return 0;
}
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Академик
320937
2216
29.02.2012, 20:50
общий
Адресаты:
Еще раз большое спасибо.
давно
Академик
320937
2216
01.03.2012, 00:21
общий
Уважаемые коллеги! Обращаю ваше внимание на вопрос 185528.
Неизвестный
01.03.2012, 17:43
общий
Адресаты:
Код:

/**------------------Задание-----------------
* Array6.
* Даны целые числа N (> 2), A и B.
* Сформировать и вывести целочисленный массив размера N,
* первый элемент которого равен A, второй равен B,
* а каждый последующий элемент равен сумме всех предыдущих.
*-------------------------------------------
*/
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
int n,sum,a,b;
system ("chcp 1251 > nul");
cout << "Введите размер массива N- ";
cin >> n;
vector<int> v(n);
cout << "Введите первый элемент - ";
cin >> a;
cout << "Введите второй элемент - ";
cin >> b;
v[0] = a;
v[1] = b;
sum = 0;
sum += v[0] + v[1];
for (vector<int>::size_type i=2;i<n;++i)
{
v[i] = sum;
sum += v[i];

}
for (vector<int>::size_type i=0;i<v.size();++i)
cout << v[i] << ' ';
return 0;

}

Уважаемый lamed исправил задачу.
давно
Академик
320937
2216
01.03.2012, 19:23
общий
Добрый вечер, Anton!
Спасибо. Но, чтобы уж совсем по фэн-шую:
1. sum=0; sum+=.... Нельзя ли обойтись одним присваиванием?
2. Вы объявляете n знаковым, i - беззнаковым.
Мне кажется, целесообразно сделать n также беззнаковым.
С уважением
Неизвестный
01.03.2012, 20:44
общий
Адресаты:
В следующий раз учту, спасибо.
давно
Академик
320937
2216
01.03.2012, 21:28
общий
А зачем ждать, Антон? Можно выложить в мини-форуме новую версию, тогда мы внесем изменения в Ваш ответ. Читатели рассылки видят только ответы
Неизвестный
04.03.2012, 20:07
общий
05.03.2012, 02:20
Адресаты:
Код:

/**------------------Задание-----------------
* Array6.
* Даны целые числа N (> 2), A и B.
* Сформировать и вывести целочисленный массив размера N,
* первый элемент которого равен A, второй равен B,
* а каждый последующий элемент равен сумме всех предыдущих.
*-------------------------------------------
*/
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
size_t n;
int sum, a, b;
system ("chcp 1251 > nul");
cout << "Введите размер массива N- ";
cin >> n;
vector<int> v(n);
cout << "Введите первый элемент - ";
cin >> a;
cout << "Введите второй элемент - ";
cin >> b;
v[0] = a;
v[1] = b;
sum = v[0] + v[1];
for (vector<int>::size_type i=2;i<n;++i)
{
v[i] = sum;
sum += v[i];

}
for (vector<int>::size_type i=0;i<v.size();++i)
cout << v[i] << ' ';
return 0;

}

Вот уважаемый lamed!
давно
Академик
320937
2216
04.03.2012, 22:24
общий
Спасибо, уважаемый Антон!
Форма ответа