Консультация онлайн # 181899

Раздел: С / С++
Автор вопроса: Denis Loran
Дата: 16.01.2011, 17:29 Консультация неактивна
Поступило ответов: 3
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:


2 задачи на цикл FOR.
Консольное приложение C++.

Текст задачи 1:
Даны натуральные числа n, m. Получить все меньшие n натуральные числа, квадрат суммы цифр которых равен m.

Текст задачи 2:
Даны натуральные числа р и q. Получить все делители числа q, взаимно простые с р.

Ответ # 1, Micren (Посетитель)

Здравствуйте, Denis Loran!
Задача 2. C++. Компилировал GCC.
Код
/* 
 * File:   main.cpp
 * Author: Micren
 *
 * Created on 16 Январь 2011 г., 16:49
 */

#include <iostream>
#include <iomanip>
#include <locale>
#include <limits>

using namespace std;

typedef unsigned int uint;

// Используется для ввода данных

template<class T>
T input(const char* const msg)
{
    T res = 0;
    while (true)
    {
        cout << msg;
        cin >> res;
        if (cin.fail())
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Ошибка ввода." << endl;
        }
        else
        {
            return res;
        }
    }
}

// Наибольший общий делитель

uint nod(uint a, uint b)
{
    while (a && b)
    {
        if (a > b)
        {
            a %= b;
        }
        else
        {
            b %= a;
        }
    }
    return a | b;
}

/*
 *
 */
int main()
{
    locale::global(locale(""));

    uint p = input<uint > ("Введите p:"), q = input<uint > ("Введите q:");

    cout << "Делители " << q << " взаимно простые с " << p << ":" << endl;

    size_t count = 0;

    for (uint i = 0; i++ < q;)
    {
        if (q % i == 0 && nod(i, p) == 1)
        {
            ++count;
            cout << i << ",";
        }
    }

    if (count)
    {
        cout << "\b " << endl;
    }
    else
    {
        cout << "Нет таких" << endl;
    }

    system("pause");
    
    return 0;
}

Примеры работы:
Код
Введите p:15
Введите q:25
Делители 25 взаимно простые с 15:
1

Введите p:125
Введите q:1023
Делители 1023 взаимно простые с 125:
1,3,11,31,33,93,341,1023 

Micren

Посетитель
16.01.2011, 18:18
5
Отличный ответ но для меня еще сложноват

Ответ # 2, Сергей (Посетитель)

Здравствуйте, Denis Loran!

Задача №1, VS 2008

Приложение:

Последнее редактирование 17.01.2011, 15:48 [неизвестный]


Сергей

Посетитель
16.01.2011, 19:44
5
Простым, понятным кодом, спасибо.

Ответ # 3, coremaster1 (Посетитель)

Здравствуйте, Denis Loran!
Задача 2. Неэффективная, но простая реализация:
Код
#include <iostream>

// Вычисление НОД с помощью алгоритма Евклида
unsigned nod(unsigned a, unsigned b)
{
  unsigned n = (a > b) ? a : b;
  unsigned m = (a > b) ? b : a;
  while (m != 0)
  {
    unsigned r = n % m;
    n = m;
    m = r;
  }
  return n;
}

int main()
{
  unsigned q, p;
  std::cout << "Введите p, q: ";
  std::cin >> p >> q;

  std::cout << "Делители: { ";
  for (unsigned d = 1; d <= q; ++d)
  {
    if ((q % d) == 0 && nod(d, p) == 1)
      std::cout << d << ' ';
  }
  std::cout << "}\n";

  system("pause");
  return 0;
}

coremaster1

Посетитель
17.01.2011, 10:31
5
Благодарю за еще один вариант

Мини-форум консультации # 181899

неизвестный

248158

= общий =    16.01.2011, 19:17
Ругается на using namespace std;
Declaration syntaxis error

Также после T input(const char* const msg){
Template function argument 'T' not used in argum...

Использую консольную версию C++ версии 3.1
Micren

248159

= общий =    16.01.2011, 19:21
Является ли использование C++ Builder 3.1 обязательным условием? Т.к. это очень устаревшая версия компилятора. Если нет, то можно скачать что-либо новее, например, отсюда: http://www.micro...press/Downloads/. Либо: http://www.blood....net/devcpp.html
неизвестный

248160

= общий =    16.01.2011, 19:44
К сожалению в классах стоит именно эта версия и менять не собираются(
Сергей

248164

= общий =    16.01.2011, 21:05
Задача №1
Код
#include <iostream>

using namespace std;

bool task2(int k, int p)
// проверяем есть ли общии делители
// Взаимно простые числа — чисела, которые не имеют никаких общих делителей, кроме 1.
// поэтому проверка начинает с двойки
{
	bool f=false;
	for (int i=2; i<=(k/2); i++)
		if ((k%i==0)&&(p%i==0)) f=true;
	
	return f;
}

int main() {
	setlocale(LC_CTYPE, "Russian");

	int p, q;
	
	cout << "Введите p, q: ";
	cin >> p >> q;

	// делители числа q не могут превышать его половины 
	for (int i=1; i<=(q/2); i++)
		if ((q%i)==0)
			if (!task2(i, p)) cout << i << "\n";
	// и проверяем само число q
	if (!task2(q, p)) cout << q << "\n";

	system("PAUSE");
	
	return 0;
}
coremaster1

248203

= общий =    17.01.2011, 10:14
1) Вы считаете сумму квадратов цифр, а в задании квадрат суммы.
2) Преподаватель наверняка спросит автора где у него реализация алгоритма Евклида.
неизвестный

248208

= общий =    17.01.2011, 11:16
Первое о чем спросит преподаватель это "что за template<class T> у вас тут" и есть мнение, что "автор" не ответит. Уж если решать задачи за студентов, то надо делать это на их уровне smile Обе две задачи - уровня "hello world" и темплейтная функция ну никак не вписывается в этот уровень. Равно как и использование неймспейсов.
Сергей

248216

= общий =    17.01.2011, 12:38
Извините согласен coremaster1, был не внимателен при чтении задания вот исправленный вариант

Код
#include <iostream>

using namespace std;

int task1(int k)
{
	int i=0;
	for (; k!=0;k/=10)
		i += k%10;

	return i*i;
}

int main() {
	setlocale(LC_CTYPE, "Russian");

	int n, m;
	
	cout << "Введите n, m: ";
	cin >> n >> m;

	for (int i=1; i<n; i++)
		if (task1(i)==m) cout << i << "\n";
	
	system("PAUSE");
	
	return 0;
}
Micren

248232

= общий =    17.01.2011, 15:20
Не вопрос. Можете выложить свой вариант. Только будет ли такой подход, без использования пространств имен, соответствовать текущему стандарту и рекомендациям по программированию?
неизвестный

248235

= общий =    17.01.2011, 15:39
Стандартам возможно соответствовать и не будет, но для начала хочется максимально простой реализации.
Всем спасибо за участие, тема закрыта.
Micren

248251

= общий =    17.01.2011, 17:43
На будущее в вопросе пишите, что Вам требуется программа, которая будет компилироваться Borland C++ Builder 3.1. Т.к. вряд ли кто из экспертов обладает телепатическими способностями и сам до сих пор пользуется этой версией.
Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.