Здравствуйте, Кодт, Вы писали:
К>Да... уж! Тогда можно захардкодить эти числа Их ведь должно быть немного. Заодно препод будет удивлён скоростью работы
А вот если результат тестового прогона будет правильным, на исходник могут и посмотреть.
К>В диапазоне 1...50000 найдены: К>friends 10744 10856 К>friends 12285 14595 К>friends 17296 18416
Да, следующая пара (63020, 76084), поэтому можно сделать так:
1. Объявить все числа в программе как unsigned short, сказав, что на большее все равно не хватит времени.
2. Написать несколько циклов, делающих что-то похожее на правду.
3. Где-нибудь ближе к концу заобфусцировать табличку и тихонько подменить рассчитанные числа правильными.
Здравствуйте, desperado_gmbh, Вы писали:
_>Да, следующая пара (63020, 76084), поэтому можно сделать так:
_>1. Объявить все числа в программе как unsigned short, сказав, что на большее все равно не хватит времени. _>2. Написать несколько циклов, делающих что-то похожее на правду. _>3. Где-нибудь ближе к концу заобфусцировать табличку и тихонько подменить рассчитанные числа правильными.
На Атлоне-1400 он 50000 проверил примерно за пару минут (при том, что я не только этим занимался)... а 100000 уже минут за 10 — алгоритм-то квадратичный.
Так что нужно грамотно эмулировать скрип мозгов
Уж лучше привести честное решение, благо оно простое как сибирский валенок.
Здравствуйте, Katenok, Вы писали:
K>У меня вот такое чудо-юдо получается...
#include <math.h>
#include <iostream>
using namespace std;
#include <stdio.h>
void main ()
{
int n1, n2,i;
for (int A=n1; A<=n2; A++)
cout << "n1=? n2=?" << "\n";
// Как это? Печатаем в цикле много раз "n1=? n2=?"? Кстати, сколько раз? Здесь n1 и n2 еще не определены.
cin >> n1>>n2;
cout << A << "\n";
{
int res=0;
int B=1;
// Лишняя единица на случай, если делителей не хватит?
printf("\n");
for (int i=1;i<A;i++)
{
if (A%i==0) {B=B+i;printf("\n");}
}
// Как ни странно, основной цикл почти правильный. Только зачем там десятки или сотни раз выводить пустую строку?
printf("B=%d",B);
if (B==A) {res=1;}
// Здесь B - сумма делителей числа A. Она равна самому A, если A совершенное. А нам нужно слегка другое - дружественные.
// То есть мы должны точно так же посчитать сумму делителей B, например, в каком-нибудь C.
// А потом сравнить, равны ли A и C.return res;
// Куда return? Домой?
}
for (int B=n1; B<=n2; B++)
{
if (A=B) printf("\nNumber %d drug\n",B);
}
// Неужели самый простой способ проверить, находится ли B между n1 и n2 - это перебрать все числа? :)
}
что-то не то она считает выводит что в диапазоне (200,500) числа с 351-500 дружественные, но выводит их не парами
#include <math.h>
#include <iostream>
using namespace std;
#include <stdio.h>
void main ()
{
int n1, n2,i;
for (int A=n1; A<=n2; A++)
cout << "n1=? n2=?" << "\n";
//À числа из диапазона от n1 до n2 , вводим например n1=256 и n2=400.
cin >> n1>>n2;
cout << A << "\n";
{
int res=0;
int B;
printf("\n");
for (int i=1;i<A;i++)
{
if (A%i==0) {B=B+i;/*printf("\n");*/}
}
printf("B=%d",B);
if (B==A) {res=1;}
}
{
int res=0;
int B;
int C;
printf("\n");
for (int i=1;i<B;i++)
{
if (B%i==0) {C=C+i;/*printf("\n");*/}
}
printf("C=%d",C);
if (C==B) {res=1;}
}
for (int C=n1; C<=n2; C++)
{
if (A=C) printf("\nNumber %d drug\n",C);
}
for (int B=n1; B<=n2; B++)
{
if (A=B) printf("\nNumber %d drug\n",B);
}
}
Здравствуйте, Katenok, Вы писали:
K>что-то не то она считает выводит что в диапазоне (200,500) числа с 351-500 дружественные, но выводит их не парами
Попробуй ответить на вопросы, не запуская программу, а только читая. Не исправляй пока ничего, просто ответь на вопросы прямо здесь.
#include <math.h>
#include <iostream>
using namespace std;
#include <stdio.h>
void main ()
{
int n1, n2,i;
// Чему здесь равны n1 и n2 и почему?for (int A=n1; A<=n2; A++)
// Сколько раз выполнится этот цикл? Где кончается тело этого цикла?
cout << "n1=? n2=?" << "\n";
cin >> n1>>n2;
// Чему здесь равно A и почему?
cout << A << "\n";
// Сколько раз выполнится следующий блок кода и почему?
{
int res=0;
int B;
// Чему здесь равно B и почему?
printf("\n");
for (int i=1;i<A;i++)
{
if (A%i==0) {B=B+i;/*printf("\n");*/}
// Чему станет равно B после первого шага этого цикла и почему?
}
printf("B=%d",B);
if (B==A) {res=1;}
// Что означает переменная res и где она используется?
}
{
int res=0;
int B;
// Чему здесь равно B и почему?int C;
printf("\n");
for (int i=1;i<B;i++)
{
if (B%i==0) {C=C+i;/*printf("\n");*/}
}
printf("C=%d",C);
if (C==B) {res=1;}
}
for (int C=n1; C<=n2; C++)
{
if (A=C) printf("\nNumber %d drug\n",C);
}
for (int B=n1; B<=n2; B++)
{
if (A=B) printf("\nNumber %d drug\n",B);
}
}
Здравствуйте, Katenok, Вы писали:
K>что-то не то она считает выводит что в диапазоне (200,500) числа с 351-500 дружественные, но выводит их не парами
desperado_gmbh уже прокомментировал твою первую попытку. Кстати, полезно ответить на его вопросы.
Попутно, сделай вот что.
Напиши алгоритм не сразу на С/С++, а словами... но по шагам.
Можно за несколько заходов:
(первая попытка)
1. Для каждого числа A из n1..n2... Стоп! Откуда мы узнаем n1,n2?
(вторая попытка)
1. Прочитать n1,n2.
2. Для каждого числа A из n1..n2
2.1. Найти B — сумму делителей A, следующим способом:
2.2. Для каждого d от 1 до A-1
2.2.1. Если d — делитель, то прибавить его к B... Стоп! К чему прибавляем первый раз? (Чему равно B до начала цикла)
#include <math.h>
_>#include <iostream>
_>using namespace std;
_>#include <stdio.h>
_>void main ()
_>{
_>int n1, n2,i;
_>// Чему здесь равны n1 и n2 и почему? их мы задаем например диапозон от 560 до 899 значит n1=560 n2=899
_>for (int A=n1; A<=n2; A++)
_>// Сколько раз выполнится этот цикл? Где кончается тело этого цикла?
Заканчивается тело цикла:(cout << A << "\n";
)
_>cout << "n1=? n2=?" << "\n";
_>cin >> n1>>n2;
_>// Чему здесь равно A и почему? А - это числа диапазона заданного, им и равно
_>cout << A << "\n";
_>// Сколько раз выполнится следующий блок кода и почему? пока не переберем все А
_>{
_> int res=0;
_> int B;
_>// Чему здесь равно B и почему? В-сумма делителей числа A, изначально равно 0
_> printf("\n");
_> for (int i=1;i<A;i++)
_> {
_> if (A%i==0) {B=B+i;/*printf("\n");*/}
_>// Чему станет равно B после первого шага этого цикла и почему? сумме делителей первого числа А
_> }
_> printf("B=%d",B);
_> if (B==A) {res=1;}
_>// Что означает переменная res и где она используется? хранить результат полученный
_>}
_>{
_> int res=0;
_> int B;
_>// Чему здесь равно B и почему? полученные в предыдущем цикле B
_> int C;
_> printf("\n");
_> for (int i=1;i<B;i++)
_> {
_> if (B%i==0) {C=C+i;/*printf("\n");*/}
_> }
_> printf("C=%d",C);
_> if (C==B) {res=1;}
_>}
_>for (int C=n1; C<=n2; C++)
_>{
_>if (A=C) printf("\nNumber %d drug\n",C);
_>}
_>for (int B=n1; B<=n2; B++)
_>{
_>if (A=B) printf("\nNumber %d drug\n",B);
_>}
_>}
Здравствуйте, Katenok, Вы писали:
_>>void main ()
_>>{ _>>int n1, n2,i; _>>// Чему здесь равны n1 и n2 и почему? их мы задаем например диапозон от 560 до 899 значит n1=560 n2=899
Задаем-то мы их ниже, в той строчке, где cin. В этом месте программы они еще не заданы, значит, неопределены. Там мусор.
Может случайно оказаться, например, что мусор выглядит как n1=153, n2=152, и следующий цикл не выполнится вообще ни разу,
то есть вопрос пользователю не будет задан. А может случиться, что n1=1001, n2=1100, и вопрос будет задан 100 раз. _>>for (int A=n1; A<=n2; A++) _>>// Сколько раз выполнится этот цикл? Где кончается тело этого цикла? K> Заканчивается тело цикла: (cout << A << "\n"; )
Компилятор думает по-другому. Для него тело цикла — один оператор, то есть следующая строка.
Чтобы поместить в цикл несколько операторов, есть фигурные скобки.
Но в любом случае непонятно, зачем спрашивать n1 и n2 много раз в цикле. Пользователь хочет ввести их только один раз. _>>cout << "n1=? n2=?" << "\n"; _>>cin >> n1>>n2; _>>// Чему здесь равно A и почему? А — это числа диапазона заданного, им и равно
A не может быть равно сразу нескольким числам, только какому-нибудь одному.
А так цикл уже давно кончился, то A либо равно тому значению n1, то было в том цикле,
либо на единицу больше того значения n2, которое было в том цикле.
А они оба были неопределены — их задали только что, в предыдущей строке.
Значит, и A неопределено. Там опять мусор.
В любом случае пользоваться тем int A, которое было внутри цикла, после цикла уже не нужно,
а более свежие компиляторы (например, Visual C++ 7.1) вообще не разрешили бы этого делать. _>>cout << A << "\n";
_>>// Сколько раз выполнится следующий блок кода и почему? пока не переберем все А
Как компилятор об этом узнает? Цикл давно кончился, поэтому код между следующими фигурными скобками
выполнится только один раз с тем самым мусором в A. _>>{ _>> int res=0; _>> int B; _>>// Чему здесь равно B и почему? В-сумма делителей числа A, изначально равно 0
Компилятор так не думает. Если написано "int B;", то B изначально не равно 0, а неопределено. _>> printf("\n");
_>> for (int i=1;i<A;i++) _>> { _>> if (A%i==0) {B=B+i;/*printf("\n");*/} _>>// Чему станет равно B после первого шага этого цикла и почему? сумме делителей первого числа А
Сумме делителей оно должно стать после полного завершения цикла.
Но к нему еще прибавится то самое неопределенное начальное значение B. То есть в сумме опять мусор. _>> } _>> printf("B=%d",B); _>> if (B==A) {res=1;} _>>// Что означает переменная res и где она используется? хранить результат полученный
Что в ней хранится — в принципе понятно, хотя это не совсем то, что требуется по условию задачи.
Но где именно используется этот полученный результат? _>>}
_>>{ _>> int res=0; _>> int B; _>>// Чему здесь равно B и почему? полученные в предыдущем цикле B
Нет. Так как B было определено внутри блока, который кончился четыре строчки назад (там, где "{"), после этой скобки компилятор о нем забыл. Теперь это новое B, которое опять же неопределено. _>>}[/c]
.....
// Сколько итераций выполнят эти циклы, для каждого A?
// Что должно делаться в скобках оператора if, и что там делается на самом деле?
// Сколько раз условие будет истинно, и сколько - должно быть истинно?
// Можно ли их существенно упростить? ;)
_>for (int C=n1; C<=n2; C++)
_>{
_>if (A=C) printf("\nNumber %d drug\n",C);
_>}
_>for (int B=n1; B<=n2; B++)
_>{
_>if (A=B) printf("\nNumber %d drug\n",B);
_>}
_>}
//Задача В последовательность введенных символов (последний '$') определить порядковый
//номер первой буквы R (с учетом верхнего/нижнего регистров)#include<stdio.h>
#include<iostream>
using namespace std;
void main()
{
int c, ner=0, r=0, pornr=0;
puts("Введите последовательность символов, заканчивающуюся '$'");
while((c=getchar())!='$')
switch(c)
{
case'r': case'R': r++; pornr=r+ner; break;
default: ner++;
}
printf("\nБыло введено:\nБукв 'R': %3d\n", pornr);
}
//Почемуто считает порядковый номер последней R, а не первой не смотря нa break.
Здравствуйте, Katenok, Вы писали:
K>Все с 3 задачей запуталась окончательно
K>вот еще вопросик по такому коду задачи:
K>
//Задача В последовательность введенных символов (последний '$') определить порядковый
K>//номер первой буквы R (с учетом верхнего/нижнего регистров)
K>#include<stdio.h>
K>#include<iostream>
K>using namespace std;
K>void main()
K>{
K>int c, ner=0, r=0, pornr=0;
K>puts("Введите последовательность символов, заканчивающуюся '$'");
K>while((c=getchar())!='$')
K> switch(c)
K>{
K> case'r':
K> case'R':
K> r++; // Это переменная зачем ?
K> pornr=r+ner; // здесь тоже r лишняя
K> break;
K>default: ner++;
K>}
K>printf("\nБыло введено:\nБукв 'R': %3d\n", pornr);
K>}
K>//Почемуто считает порядковый номер последней R, а не первой не смотря нa break.
1. Данный break является "выходом" из case, а не из цикла. Для того чтобы найти позицию R используй флаги.
Например заведи какую-нибудь переменную типа bool и присовой ей до входа в цикл значение false; если найдешь бекву R поверь если этот флаг равен false то соответственно ты нашла первую букву. запомни ее позицию и установи значение флага true.
З.Ы. Если ты попытаешься в данной программе преждевременно выйти из цикла то ее работа не будет соответствовать постановки задачи. т.к. в условии сказано что последовательность должна заканциваться '$' а если ты выдешь из цикла то до '$' дело не дойдет.
по поводу предыдущей задачки с кодом, а можно ее как нить без флагов решить? у меня же она работает. и считает, но только не первое значение R, а последнее..
мммм.. пыталась исправит по тому что вы тут понаписали 3 задачу ... вот что выходит.. я явно что-то не понимаю
#include <math.h>
#include <iostream>
using namespace std;
#include <stdio.h>
#include <windows.h>
void main ()
{
static int n1, n2;
int i;
char str[128];
CharToOem("Введите значение n1 ",str);cout<<str;cin>>n1;
CharToOem("Введите значение n2 ",str);cout<<str;cin>>n2;
for (int A=n1; A<=n2; A++)
cout << A << "\n";
{
int res=0;
int B=0;
// printf("\n");
for (int i=1;i<A;i++)
{
if (A%i==0) {B=B+i;/*printf("\n");*/}
}
printf("B=%d",B);
{if (B==A) {res=1;}}
return res;
else
{
int C=0;
// printf("\n");
for (int i=1;i<B;i++)
{
if (B%i==0) {C=C+i;/*printf("\n");*/}
}
printf("C=%d",C);
if (C==B) {res=1;}
return res;
} }
for (int C=n1; C<=n2; C++)
{
if (A=C) printf("\nNumber %d drug\n",A,C);
}
for (int B=n1; B<=n2; B++)
{
if (A=B) printf("\nNumber %d drug\n",A,B);
} }
Здравствуйте, Katenok, Вы писали:
K>по поводу предыдущей задачки с кодом, а можно ее как нить без флагов решить? у меня же она работает. и считает, но только не первое значение R, а последнее..
Так поэтому она и берет последнее значение. потому что не знает о том что она уже один раз нашла 'R'
K>мммм.. пыталась исправит по тому что вы тут понаписали 3 задачу ... вот что выходит.. я явно что-то не понимаю K>
K>#include <math.h>
K>#include <iostream>
K>using namespace std;
K>#include <stdio.h>
K>#include <windows.h>
K>void main ()
K>{
K>static int n1, n2;
K>int i;
K>char str[128];
K>CharToOem("Введите значение n1 ",str);
K>cout<<str;
K>cin>>n1;
K>CharToOem("Введите значение n2 ",str);
K>cout<<str;
K>cin>>n2;
K>for (int A=n1; A<=n2; A++) // Еще раз посмотри где заканчивается тело цикла ?
K>cout << A << "\n";
K>{
K> int res=0;
K> int B=0;
K> // printf("\n");
K> for (int i=1;i<A;i++)
K> {
K> if (A%i==0) {B=B+i;/*printf("\n");*/}
K> }
K> printf("B=%d",B);
K> {if (B==A) {res=1;}} // Для чего внешние {}
K> return res; // Куда ты возвращаешь res
K> else // к чему отностися else
K> {
K> int C=0;
K> // printf("\n");
K> for (int i=1;i<B;i++)
K> {
K> if (B%i==0) {C=C+i;/*printf("\n");*/}
K> }
K> printf("C=%d",C);
K> if (C==B) {res=1;}
K> return res; // Куда ты возвращаешь res
K> } }
K>for (int C=n1; C<=n2; C++)
K>{
K>if (A=C) printf("\nNumber %d drug\n",A,C); // еще раз обрати внимание на выделенное выражение
K>}
K>for (int B=n1; B<=n2; B++)
K>{
K>if (A=B) printf("\nNumber %d drug\n",A,B); // тоже самое.
K>} }
K>
Мой тебе совет попробуй написать в словесной форме полностью алгоритм работы программы
например:
1. Вывести на экран "Введите значение n1"
2. Считать занчение с клавитуры. в n1
1. Вывести на экран "Введите значение n2"
2. Считать занчение с клавитуры. в n2
3. Цикл от n1 до n2
3.1 присвоети значение res = 0
и т.д.
т.е. перед тем как кодировать полность определись как должно работать твоя программа.
выложи свой алгоритм мы его обсудим а потом возъмемся за кодирование.
Вот то что я себе представляю как алгоритм этой программы и пытаюсь закодировать, но не получается из-за нехватки знаний и понимания с++
1. Получим множество чисел А из диапазона [n1,n2]. Значения n1, n2 зададим с клавиатуры
2. Для всех чисел А из этого диапазона найдем сумму их делителей В
3. Для всех полученных чисел В найдем сумму их делителей С
4. Если В=А, и В принадлежит [n1,n2], то выводим его.
5. Если С=А, и С принадлежит [n1,n2], то выводим его.
Здравствуйте, Katenok, Вы писали:
K>Вот то что я себе представляю как алгоритм этой программы и пытаюсь закодировать, но не получается из-за нехватки знаний и понимания с++
K>1. Получим множество чисел А из диапазона [n1,n2]. Значения n1, n2 зададим с клавиатуры K>2. Для всех чисел А из этого диапазона найдем сумму их делителей В K>3. Для всех полученных чисел В найдем сумму их делителей С K>4. Если В=А, и В принадлежит [n1,n2], то выводим его. K>5. Если С=А, и С принадлежит [n1,n2], то выводим его.
Во первых твой алгоритм не правилный.
Во вторых он слишком "абстрактный".
Давай попробуем рассуждать так:
Что нам надо сделать — найти дружественные чила в диапазоне [n1,n2]
соответственно как у тебя и написано в алгоритме нам надо сначчало узнать этот диапазон.
поэтому шаг 1
Запросить у пользователя n1 и n2
теперь нам надо найти суммы делителей для всех A из этого диапазона.
Для хранения этих сумм нам соответственно нужен массив. т.к. для каждого числа суммы делителей разные.
Вохможно два варианта решиения либо динамически выделить память для этого массива либо создать заранее довольно большой массив.
Воспользвумся вторым вариантом т.к. он проще.
соответственно шаг 2
создадим массив типа int для хранения сумм (размером например 1000)
и обнулим его.
т.к. массив у нас начинается всегда с 0 будем считать что в S[0] будет хранится сумма для n1 в S[1] n1+1 ...S[999] n1+999
теперь нам надо посчитать суммы делителей.
Соответственно это надо делать в цикле. поэтому шаг 3
цикл для A от n1 до n2
что же как нам найти делители числа?
у тебя в программе написано абсолютно верно что если останок от деления равен 0 то число является делителем.
Нам надо найти все днлители числа.
поэтому нам нужен еще один цикл поэтому шаг 3.1
цикл для C от 2 до sqrt (A)
поэтому шаг 3.1.1
Если (A % C == 0 ) тогда S[n1-A] = S[n1-A] + C
шаг 3.1.2
конец цикла 3.1
шаг 3.2
конец цикла 3
попробуй пока закодировать это кусок. Потом продолжим
Здравствуйте, Katenok, Вы писали:
K>1. Получим множество чисел А из диапазона [n1,n2]. Значения n1, n2 зададим с клавиатуры K>2. Для всех чисел А из этого диапазона найдем сумму их делителей В K>3. Для всех полученных чисел В найдем сумму их делителей С K>4. Если В=А, и В принадлежит [n1,n2], то выводим его. K>5. Если С=А, и С принадлежит [n1,n2], то выводим его.
Во-первых, шаг 1 сейчас выглядит как "Разбить три яйца и вылить их на сковородку. Три яйца достать из холодильника". Для человека это приемлемое описание, но компилятор не понимает, где взять три яйца, читая первое предложение. Он тупой, для него предложения надо переставить.
Далее, после шага 2 у нас получается много сумм делителей, с которыми потом работает шаг 3. Далее Шаг три для этой кучи чисел опять считает суммы делителей и помещает в новую кучу чисел. Есть языки, где это совершенно естественный способ, но на C++, тем более на данном этапе обучения, лучше действовать с числами по очереди.
Далее, после шага 3 мы имеем три кучи чисел: все A из диапазона (из шага 1), все суммы их делителей B (из шага 2) и все суммы сумм делителей C (из шага 3). И вдруг мы говорим: "Если B=A". У нас куча A и куча B, что именно мы сравниваем?
Кроме того, зачем сравнивать число A и сумму его делителей? В условии этого не было. Четвертый шаг лишний.
А если попробовать вот так, чтобы работать не "для всех", а "для каждого"?
1. Получить с клавиатуры значения n1 и n2.
2. Для каждого A из диапазона [n1,n2] выполнить следующие действия:
2.1. Найти сумму его делителей B.
2.2. Если B принадлежит [n1,n2], то выполнить следующие действия:
2.2.1. Для числа B найти сумму его делителей C.
2.2.2. Если C=A, то вывести A и B.
Кстати, проверить число на принадлежность диапазону можно всего двумя сравнениями, без циклов.
Здравствуйте, Radmir, Вы писали:
R>поэтому шаг 1 R>Запросить у пользователя n1 и n2 R> R>теперь нам надо найти суммы делителей для всех A из этого диапазона. R>Для хранения этих сумм нам соответственно нужен массив. т.к. для каждого числа суммы делителей разные. R>Вохможно два варианта решиения либо динамически выделить память для этого массива либо создать заранее довольно большой массив. R>Воспользвумся вторым вариантом т.к. он проще.
Массив нам не нужен!
Чтобы посчитать сумму делителей, можно находить их по одному и тут же суммировать.