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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 14.03.2008, 19:23   #1
Foky
Пользователь
 
Регистрация: 14.03.2008
Сообщений: 32
По умолчанию Задачи на множества

Помогите плиз решить 2 задачи:
1,В возpастающем поpядке напечатать все целые числа из диапазона 1..10000, пpедставимые в виде
n *n + m*m ,где n,m>0.
2,Нужно ввести с клавиатуры некоторую последовательность символов, а программа должна вывести символы из диапазона от a до f и от x до z, елси таковые имеются в вводимой последовательности. Вот решала задачу через константу, а через множество не знаю.
Foky вне форума Ответить с цитированием
Старый 14.03.2008, 19:52   #2
puporev
Старожил
 
Регистрация: 13.10.2007
Сообщений: 2,740
По умолчанию

Если решали через константу, то она наверняка была множеством. Можно и эту вторую задачу решить с помощью константы-множества. Но если нужно именно через множества, тогда так.
Код:
uses crt;
var s:string;
    m1,m2:set of char;//объявляем тип множество символов
    i:integer;
begin
clrscr;
write('s:');readln(s);//вводим строку
m1:=['a'..'f'];          //заполняем множества по условию
m2:=['x'..'z'];
for i:=1 to length(s) do
if (s[i] in m1)or(s[i]in m2)then
     begin
      write(s[i]);        //выводим нужные символы
     end;
readln
end.
puporev вне форума Ответить с цитированием
Старый 14.03.2008, 20:23   #3
Foky
Пользователь
 
Регистрация: 14.03.2008
Сообщений: 32
По умолчанию

Спс за вторую задачу).
я её решала так:
uses crt;
const bucva=['a','b','c','d','e','f','x','y','z'];
var
x:char;
i:byte;
s:string;
begin
clrscr
write('vvedite posledovatelnost');
readln(s);
for i:=1 to lentgth(s) do
if s[i] in bucva
then write (s[i]);
readln;
end.
ps:помоги плиз решить первую задачу через множества, если тебе не трудно плииииз; буду весьма благодарна
Foky вне форума Ответить с цитированием
Старый 14.03.2008, 22:42   #4
puporev
Старожил
 
Регистрация: 13.10.2007
Сообщений: 2,740
По умолчанию

Провозился с первой задачей, пока не понял, что для обычной рабрты в Паскале 10000 это много, программа очень долго считает, почти зависает. Для 1000 работает быстро, но чисел очень много и на экране плохо понятный бардак, видимо результат лучше ваводить в файл.
Остановился на 500. И работает быстро и экрана хватает.
Код:
uses crt;
var m:set of byte;  //множество квадратов чисел
    a:array[1..500]of integer;  //массив сумм квадратов
    i,j,k,x:integer;
begin
clrscr;
m:=[];  //пустое множество
for i:=1 to 22 do
include(m,sqr(i));  //заполняем квадратами не более 500
k:=0;
for i:=1 to 484 do  /22^2
for j:=i to 484 do  //обратите внимание, не j:=1 to 484 ,а j:=i to 484 
if(i<>j)and(i in m)and(j in m)and((i+j)<=500)
then begin
     k:=k+1;  //считаем суммы
     a[k]:=(i+j);//заносим их в массив
     end;
//сортируем массив по возрастанию, здесь основная задержка, т.к. сортировка пузырьком самая медленная, а другой у меня под рукой нет, это можно переделать.
for i:=1 to k-1 do  
for j:=1 to k-1 do
if a[j]>a[j+1] then
    begin
      x:=a[j];a[j]:=a[j+1];a[j+1]:=x;
    end;
for i:=1 to k do
write(a[i],' ');  //выводим результат
readln
end.
Чтобы задачу решить так как она задана, надо принимать дополнительные меры.
puporev вне форума Ответить с цитированием
Старый 14.03.2008, 23:17   #5
Foky
Пользователь
 
Регистрация: 14.03.2008
Сообщений: 32
По умолчанию

Ыыы... давольная как слон. Спасибо огромное тебе:сама бы решала вечность.
Foky вне форума Ответить с цитированием
Старый 15.03.2008, 16:00   #6
Plague
Забанен
Форумчанин Подтвердите свой е-майл
 
Аватар для Plague
 
Регистрация: 01.11.2006
Сообщений: 420
По умолчанию

Задача № 1
Код:
var i,j,t,n:integer;
begin
  i:=1;
  j:=1;
  for n:=1 to 10000 do
  begin
    t:=0;
    for i:=round(int(sqrt(n))) downto 1 do
    begin
      for j:=1 to i do
        if i*i+j*j = n then
          begin
            t:=1;
            break;
          end;
        if t=1 then break;
    end;
    if t=1 then write(n,' ');
  end;
  writeln;
end.
to Foky
множество добавить только осталось

to puporev
в ващем решении числа дублируются
Если ничто другое не помогает, прочтите, наконец, инструкцию! Аксиома Кана
Plague вне форума Ответить с цитированием
Старый 15.03.2008, 21:20   #7
Foky
Пользователь
 
Регистрация: 14.03.2008
Сообщений: 32
По умолчанию

Первый раз когда вводила твою программу, она у меня подвисла на 100).Второй раз выполнялось хорошо. Не знаю, мб я не в тему, всё-таки я сама задачу не решала, но насколько я знаю break, halt и вроде exit рекомендуется употреблять в крайних случаях, когда невозможно по другому выйти из цикла, т.к. при таком выходе память не очищается.
ps: спасибо за решение
Foky вне форума Ответить с цитированием
Старый 15.03.2008, 22:06   #8
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Мой вариант задачи №1. Работает быстро даже при 100000:

Код:
const N=100000;

var //Массив минимальных количеств слагаемых
    list:array [1..N] of integer;
    i,j, //Индексы
    t,   //Квадрат индекса
    u,   //Следующее число
    v,   //Его квадрат
    min:integer; //Минимум на массиве
    stop:boolean; //Останов цикла

begin
    list[1]:=1; //1=1^2
    v:=4;       //Следующий квадрат - 4
    u:=2;       //Индекс - 2 (2^2=4)
    for i:=2 to N do
    begin
        if i=v then //Если это квадрат
        begin
            //То слагаемое только 1
            list[i]:=1;
            //Следующее число
            inc(u);
            v:=u*u
        end
        else
        begin
            //Считаем, что число представимо только суммой единиц
            min:=i;

            j:=1;
            t:=1;

            stop:=false;
            while not stop do
            begin
                //Пока не вышли за пределы массива
                stop:=t>=i;
                if not stop then
                    //Минимум слагаемых чисел i-j^2
                    if list[i-t]<min then
                        min:=list[i-t];
                inc(j);
                t:=j*j
            end;
            //Если существует j: i-j^2=k^2, то число найдено
            if min=1 then
                write(i,' ');
            //Слагаемых на единицу больше
            list[i]:=min+1;
        end;
    end;

    readln
end.
ЗЫ Если увеличивать пределы массива, то для Паскаля нужно соответствующие переменные сделать longint.

Последний раз редактировалось Carbon; 15.03.2008 в 22:09.
Carbon вне форума Ответить с цитированием
Старый 15.03.2008, 22:56   #9
Foky
Пользователь
 
Регистрация: 14.03.2008
Сообщений: 32
По умолчанию

Цитата:
Сообщение от Carbon Посмотреть сообщение
Мой вариант задачи №1. Работает быстро даже при 100000:

Код:
const N=100000;

var //Массив минимальных количеств слагаемых
    list:array [1..N] of integer;
    i,j, //Индексы
    t,   //Квадрат индекса
    u,   //Следующее число
    v,   //Его квадрат
    min:integer; //Минимум на массиве
    stop:boolean; //Останов цикла

begin
    list[1]:=1; //1=1^2
    v:=4;       //Следующий квадрат - 4
    u:=2;       //Индекс - 2 (2^2=4)
    for i:=2 to N do
    begin
        if i=v then //Если это квадрат
        begin
            //То слагаемое только 1
            list[i]:=1;
            //Следующее число
            inc(u);
            v:=u*u
        end
        else
        begin
            //Считаем, что число представимо только суммой единиц
            min:=i;

            j:=1;
            t:=1;

            stop:=false;
            while not stop do
            begin
                //Пока не вышли за пределы массива
                stop:=t>=i;
                if not stop then
                    //Минимум слагаемых чисел i-j^2
                    if list[i-t]<min then
                        min:=list[i-t];
                inc(j);
                t:=j*j
            end;
            //Если существует j: i-j^2=k^2, то число найдено
            if min=1 then
                write(i,' ');
            //Слагаемых на единицу больше
            list[i]:=min+1;
        end;
    end;

    readln
end.
ЗЫ Если увеличивать пределы массива, то для Паскаля нужно соответствующие переменные сделать longint.
Мозг блондинки не способен понять, что ты там написал
Да и ктому же программа выдала ошибку о переполнении, короче паскаль подвис у меня).
Foky вне форума Ответить с цитированием
Старый 15.03.2008, 23:19   #10
puporev
Старожил
 
Регистрация: 13.10.2007
Сообщений: 2,740
По умолчанию

Вариант Plague нормально работает, только как туда множества засунуть, ведь тема на множества. Кстати, чтобы в врианте Plague сделать нормальный вsвод нужно слегка переделать конец и вывод будет порциями с задержкой.
Код:
    if t=1 then break;   
end;   
             if t=1 then write(n,' '); 
             if n mod 1000=0 then readln  
end;   
end.
puporev вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Множества Zid@ne Помощь студентам 16 20.01.2008 10:19
Множества в Си Иллидан Общие вопросы C/C++ 14 17.01.2008 15:58
Задачи по теме множества Hostlman Общие вопросы Delphi 2 22.12.2007 21:52