Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.06.2008, 08:44   #1
SYL@R
Пользователь
 
Регистрация: 09.06.2008
Сообщений: 25
По умолчанию помогите с задачками

1.Написать программу, позволяющую по последней цифре числа определить последнюю цифру его квадрата.
2.Даны натуральные числа р и q. Получить все делители числа q, взаимно простые с р.
SYL@R вне форума Ответить с цитированием
Старый 09.06.2008, 09:50   #2
master_root
Пользователь
 
Регистрация: 18.05.2008
Сообщений: 30
По умолчанию

1.Функция в аргументе получает число в результате выдаёт последнюю цифру его квадрата:
Код:
function func(num: integer): integer;
var
	lnum: integer;//временная переменная для хранения последней цифры заданного числа
	lstr: string;//временная переменная для выделения из числа посденей цифры
begin
{выделение последней цифры из заданного числа}
	lstr:=inttostr(num);//преобразуем тип из целочисленного в строковой
	lstr:=lstr[Length(lstr)];//выделяем последнюю цифру
	lnum:=strtoint(lstr);//преобразуем строку в число
{анализ последней цифры заданного числа}
	case lnum of
		0,1,5,6: func:=lnum;//если цифра 0,1,5 или 6,то последняя цифра квадрата числа такая же
		2,3: func:=sqr(lnum);//если цифра 2 или 3 то последняя цифра квадрата соответствует квадрату этой цифры
		4: func:=6;
		7: func:=9;
		8: func:=4;
		9: func:=1;
	else//если что-то ещё,то это скорее всего ошибка и выдаём нереальное число -1 для опознования
		func:=-1;
	end;
end;

Последний раз редактировалось master_root; 09.06.2008 в 10:31.
master_root вне форума Ответить с цитированием
Старый 09.06.2008, 10:11   #3
SYL@R
Пользователь
 
Регистрация: 09.06.2008
Сообщений: 25
Плохо

надо через операторы ветвления и циклов

Последний раз редактировалось SYL@R; 09.06.2008 в 10:17.
SYL@R вне форума Ответить с цитированием
Старый 09.06.2008, 10:24   #4
master_root
Пользователь
 
Регистрация: 18.05.2008
Сообщений: 30
По умолчанию

вот теперь всё работает. Ошибка была вот здесь:
Код:
lstr:=lstr[Length(lstr)-1];//выделяем последнюю цифру
Я выделял предпоследнюю цифру.А чтобы выделить последнюю соответственно вычитать единицу не нужно. Функция 100% работает
>SYL@R
А чем тебе Case..Of не ветвление?Одни и теже задачи можно решить разными путями - это естественно. Делай по-другому, мне даже интересно посмотреть насколько производительней и короче можно реализовать этот алгоритм

Последний раз редактировалось master_root; 09.06.2008 в 10:30.
master_root вне форума Ответить с цитированием
Старый 09.06.2008, 10:29   #5
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

end после строкой 20 добавить надо
eoln вне форума Ответить с цитированием
Старый 09.06.2008, 10:32   #6
SYL@R
Пользователь
 
Регистрация: 09.06.2008
Сообщений: 25
По умолчанию

а вторую задачу
SYL@R вне форума Ответить с цитированием
Старый 09.06.2008, 11:13   #7
master_root
Пользователь
 
Регистрация: 18.05.2008
Сообщений: 30
По умолчанию

2.Функция возвращает строку, содержащую список взаимно простых с натуральным числом p делителей натурального числа q, разделённых пробелами.
Код:
function func(q,p: integer): string;
var
	i: integer;//делители числа q
	j: integer;//делители для определения взаимно простых чисел
  tmp_str: string;//временная строка для форматирования результата функции
  eq: boolean;//если true - числа взаимно простые иначе false
begin
eq:=false;//начальное значение
{цикл перебора делителей числа q}
for i:=1 To q do//делитель не может быть больше числа q, т.к. нам нужны делители только делящие нацело
	if (q mod i)=0 then//проверка делителя на то, что он делит нацело
	begin//если делитель делит на цело
		{цикл перебора делителей для проверки на то, что делитель i - взаимно простое число с p}
		for j:=1 to i do//этот делить тоже должен делить на цело и соответственно не может быть больше делимого
		begin
			if (i mod j)=0 then//проверка на то,то делитель делит нацело
				if (p mod j)<>0 then//если да то проверяем делится ли p на этот же делитель и если нет
					eq:=true    //присваиваем eq значение истина
				else//если да , то присваиваем значение ложь
					eq:=false;
		end;
		{анализ результата}
		if eq=true then//если i - делитель - это взаимно простое число с p, то
		begin
			tmp_str:=tmp_str+inttostr(i)+' ';//добавляем его в список результата
			eq:=false;//обнуляем условие
		end;
	end;
result:=tmp_str;//вывод результата
end;
Код 100% работает. С условием что, взаимно простые числа - целые неотрицательные числа не имеющие общих делителей кроме 1. Если не понятно что спрашивай

Последний раз редактировалось master_root; 09.06.2008 в 11:27.
master_root вне форума Ответить с цитированием
Старый 09.06.2008, 14:38   #8
Sunrise
Пользователь
 
Регистрация: 09.06.2008
Сообщений: 20
По умолчанию

Код:
 if (i mod j)=0 then//проверка на то,то делитель делит нацело  
                 if (p mod j)<>0 then//если да то проверяем делится ли p на этот же делитель и если нет  
                     eq:=true    //присваиваем eq значение истина  
                 else//если да , то присваиваем значение ложь  
                     eq:=false;
Получается, что eq зависит только от того, делится ли p на i или нет. Если мы нашли делитель i, на который делится p, то нужно сразу сделать break.
Кстати, задачу можно решить и более эффективно:
Код:
#include <cstdio>
using namespace std;

int gcd(int a, int b) {
	if (b == 0) return a;
	else return gcd(b, a % b);
}

int main() {
	int p, q;
	scanf("%d %d", &p, &q);
	for (int i = 1; i*i <= q; ++i) {
		if (q % i == 0) {
			if (i != 1 && gcd(p, i) == 1) printf("%d\n", i);
			if (q / i != 1 && gcd(p, q / i) == 1) printf("%d\n", q / i);
		}
	}
}
Sunrise вне форума Ответить с цитированием
Старый 09.06.2008, 18:40   #9
master_root
Пользователь
 
Регистрация: 18.05.2008
Сообщений: 30
По умолчанию

>Sunrise
Да согласен, нужно поставить break; в проверку
Код:
                else//если да , то присваиваем значение ложь    
                begin
                      eq:=false;  
                      break;
                end;
насчёт эффективности твоего алгоритма с моим я бы поспорил. Да строчек кода на первый взгляд у тебя меньше, но ты подключаешь ещё модуль <cstdio> и используешь его функции. И получается он медленнее чем мой,т.к. я использую только стандартыне определения языка.
master_root вне форума Ответить с цитированием
Старый 09.06.2008, 18:49   #10
Sunrise
Пользователь
 
Регистрация: 09.06.2008
Сообщений: 20
По умолчанию

Асимптотика твоего алгоритма: O(q ^ 2)
Моего: либо O(sqrt(q) * log q), либо O(sqrt(q) * log p), наибольшее из них.
Эффективность моего налицо.
Sunrise вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите с задачками о матрицах(( Colette Паскаль, Turbo Pascal, PascalABC.NET 2 27.05.2008 09:37
Помогите с задачками Mi$ter Фриланс 1 15.05.2008 09:59
Помогите с задачками по Паскалю NTFS Помощь студентам 3 22.04.2008 21:27
Помогите с задачками lexIS Помощь студентам 0 05.12.2007 23:17
Помогите с задачками OlgaMiller Общие вопросы C/C++ 25 25.10.2007 21:05