БлогNot. 31 не пригодившаяся в декабре задачка

31 не пригодившаяся в декабре задачка

Часть программок, сделанных за декабрь, которые не пригодились совсем никак... даже если на каждую потрачено 5 минут, это 2,5 часа потерянного времени. Размещу, чтобы догнать потери до трёх часов :)

Забивать таким ленту, создавая отдельные темы, не хочется, но и выбрасывать жалко... Если зашли на страницу с поисковика, помните про комбинацию клавиш Ctrl+F - поиск на странице.

1. Выполните перегрузку операции "*" для скалярного умножения одномерных массивов (Visual C++)

#include <iostream>
using namespace std;
 
class VECTOR {
 public:
  float *c;
  int n;
  VECTOR (int n=2);
  ~VECTOR();
  float operator * (VECTOR &);
  float & operator [] (int i) { return c[i]; }
};
 
VECTOR::VECTOR (int n) {
 this->n=n;
 c= new float [n];
 for (int i=0; i<n; i++) c[i]=0;
}
 
VECTOR::~VECTOR () {
 delete c;
}
 
float VECTOR::operator * (VECTOR &p) {
 int i; float s=0;
 for (i=0; i<n; i++) s+=this->c[i]*p.c[i];
 return s;
}
 
void main () {
 VECTOR a(2);
 a[0]=1; a[1]=2;
 VECTOR b(2);
 b[0]=3; b[1]=4;
 float c = a * b;
 cout << "C=" << c;
 cin.get();
}

2. Дан массив записей, содержащих дату (число, месяц, год) и время (час, минута, секунда). Упорядочить этот массив в порядке "возрастания", т.е. от более ранних значений к более поздним. (консольный Си)

Простейшее решение "в лоб" такое:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct datetime {
 int day,mon,year,hour,min,sec;
};
 
int dates_compare(datetime d1,datetime d2) {
 if (d1.year>d2.year) return 1;
 else if (d1.year<d2.year) return -1;
 else {
  if (d1.mon>d2.mon) return 1;
  else if (d1.mon<d2.mon) return -1;
  else {
   if (d1.day>d2.day) return 1;
   else if (d1.day<d2.day) return -1;
   else {
    if (d1.hour>d2.hour) return 1;
    else if (d1.hour<d2.hour) return -1;
    else {
     if (d1.min>d2.min) return 1;
     else if (d1.min<d2.min) return -1;
     else {
      if (d1.sec>d2.sec) return 1;
      else if (d1.sec<d2.sec) return -1;
      else return 0;
     }
    }
   }
  }
 }
}
 
int main() {
 const int n=10;
 datetime d[n];
 int i,j;
 
 printf ("\nИсходные данные");
 for (i=0; i<n; i++) { //вводить столько информации с клавы мне лень
  d[i].day=1+random(28);
  d[i].mon=1+random(12);
  d[i].year=2000+random(14);
  d[i].hour=random(24);
  d[i].min=random(60);
  d[i].sec=random(60);
  printf ("\n%02d.%02d.%4d, %02d:%02d:%02d",
   d[i].day,d[i].mon,d[i].year,d[i].hour,d[i].min,d[i].sec);
 }
 
 datetime temp;
 for (i=0; i<n-1; i++)
 for (j=i+1; j<n; j++)
 if (dates_compare(d[i],d[j])>0) {
  temp=d[i]; d[i]=d[j]; d[j]=temp;
 }
 
 printf ("\nОстортированные данные");
 for (i=0; i<n; i++)
  printf ("\n%02d.%02d.%4d, %02d:%02d:%02d",
   d[i].day,d[i].mon,d[i].year,d[i].hour,d[i].min,d[i].sec);
 
 printf("\n");
 system("pause");
 return 0;
}
Исходные данные
01.01.2004, 00:21:13
16.03.2009, 22:16:26
04.09.2007, 00:09:48
20.10.2011, 23:13:25
27.11.2012, 19:27:36
19.08.2007, 17:06:24
04.09.2006, 11:33:20
25.04.2002, 10:41:09
16.08.2008, 00:47:16
13.05.2005, 13:36:16
Остортированные данные
25.04.2002, 10:41:09
01.01.2004, 00:21:13
13.05.2005, 13:36:16
04.09.2006, 11:33:20
19.08.2007, 17:06:24
04.09.2007, 00:09:48
16.08.2008, 00:47:16
16.03.2009, 22:16:26
20.10.2011, 23:13:25
27.11.2012, 19:27:36
Нажмите любую клавишу...

3. Написать программу, которая вычисляет сколько дней осталось до нового года от заданной даты (консольный Си)

#include <stdio.h>
#include <stdlib.h>
 
int KolDays (int d1,int m1,int y) {
 int i,s,d2=31,m2=12;
 int mondays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
 if ((y%4==0) && (y%100!=0) || (y%400==0)) mondays[1]=29;
 if (m1==m2) s=d2-d1;
 else {
  s=mondays[m1-1]-d1+1;
  for (i=m1+1;i<m2;i++) s+=mondays[i-1];
  s+=(d2-1);
 }
 return s;
}
 
void main () {
 printf ("%d\n",KolDays (1,1,2012));
 printf ("%d\n",KolDays (1,1,2013));
 printf ("%d\n",KolDays (20,12,2013));
 printf ("%d\n",KolDays (31,12,2013));
 system("pause");
}

или вернуть из функции s+1 если считать, что от 31 декабря до НГ не 0 дней, а 1.

Если нужен ввод даты с клавиатуры - реализуйте самостоятельно.

4. Даны три числа D, M и G, определяющие день, месяц и год. Проверить образуют ли они правильную дату и вывести соответствующее сообщение. (консольный Си, фрагмент)

Функции, делающие нужные проверки:

int mondays[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
 
int leapYear (int y) {
 return ( (y%4==0) && (y%100!=0) || (y%400==0) );
}
 
int correctDate (int d,int m,int y) {
 if (leapYear(y)) mondays[1]=29;
 if (d<1 || d>mondays[m-1] || m<1 || m>12) return 0;
 return 1;
}

без ограничений на год, иначе можно в последней функции добавить их.

5. Решить методом дихотомии уравнение sin x + cos 2x = 0

Корень находится в интервале (2,4), т.е., задан интервал изоляции.

Допустимая погрешность вычисления корня составляет 0.5 * 10-4 (консольный Си)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
double f (double x) {
 return sin(x)+cos(2*x);
}
 
int main () {
 double a=2,b=4,c=(a+b)/2.;
 while (fabs(f(c))>0.5e-4) {
  if (f(a)*f(c)>0) a=c;
  else b=c;
  c=(a+b)/2.;
 }
 printf ("\nx=%lf, f(x)=%lf",c,f(c));
 system ("pause");
 return 0;
}

6. Вывести на экран таблицу перевода расстояний в дюймах в сантиметры для значений 2,4,6,...,12 дюймов (1 дюйм=25.4 мм) (Visual C++)

#include <iostream>
using namespace std;
 
int main () {
 int inch;
 float cm;
 for (inch=2; inch<14; inch+=2) {
  cm=inch*2.54;
  cout << inch << " in = " << cm << " cm " << endl;
 }
 cin.sync(); cin.get();
 return 0;
}

7. В григорианском календаре каждый год, номер которого делится на 4, является високосным, за исключением тех, которые делятся на 100 и не делятся на 400 нацело. Определить число дней в году по номеру года. (консольный Си, фрагмент)

//y - 4-значный год
if (y%4==0 && y%100!=0 || y%400==0) d=366; 
else d=365;

8. Дано число A (> 1). Вывести наибольшее из целых чисел K, для которых сумма 1 + 1/2 + ... + 1/K будет меньше A, и саму эту сумму. Решить задачу, используя оператор цикла while (консольный Си)

#include <conio.h>
#include <iostream.h>
void main() 
{
double N,K,S;
cout<<"vvedite N";
cin>>N;
K=1.0;
S=0.0;
while(S<N) 
{S+=1/K; K++;} 
S-=1/K;K--;
cout<<"Naimenshee celoe" << K << endl;
cout<<"Summa" << S << endl;
getch();
}

9. Найти первые N натуральных чисел – палиндромов (консольный Си)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
char buf[20];
 
int pal (unsigned long int k) {
 int i=0,j;
 while (k) { buf[i++]=k%10; k/=10; }
 for (j=0; j<i/2; j++) if (buf[j]!=buf[i-1-j]) return 0;
 return 1;
}
 
int main () {
 unsigned long int n=1000,i=0,k=10;
 while (i<n) {
  if (pal(k)) { printf ("%lu ",k); i++; }
  k++;
 }
 system ("pause");
 return 0;
}

Использование buf - примитивно. Лучше бы узнать количество цифр в числе (функция count_digits отсюда) и выделить память под буфер нужного размера.

10. Вводится число N (N<=100). Выдать все простые числа в диапазоне от 2 до N, заполнив массив числами от 2 до N, а затем обнулить все кратные 2, затем все кратные 3 и т.д. Необнулённые элементы и будут простыми числами (консольный Си)

#include <stdio.h>
#include <stdlib.h>
 
int main () {
 const int nmax=100;
 int a[nmax],i,n,k;
 printf ("\nВведите размерность массива от 2 до %d:",nmax);
 scanf ("%d",&n);
 a[0]=0; //1 - не простое число!
 for (i=1; i<n; i++) a[i]=i+1;
 for (k=2; k<=n/2; k++) for (i=0; i<n; i++) if (a[i]!=k && a[i]%k==0) a[i]=0;
 printf ("\nПростые числа: ");
 for (i=0; i<n; i++) if (a[i]!=0) printf ("%d ",a[i]);
 system ("pause");
 return 0;
}

11. Имеется строка, нужно поменять местами слова: 1-ое со 2-ым, 3-е с 4-ым и т.д. Написать простой код на чистом Си, функции работы со строками использовать разрешено.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main() {
 char s[256],*words[128];
 char *d=" ,.";
 int count=0;
 printf("Enter your string:\n");
 gets (s);
 char *p;
 p=strtok(s, d);
 while (p) {
  words[count] = (char *) malloc (strlen(p)+1);
  strcpy (words[count],p); count++;
  p=strtok(NULL, d);
 }
 for (int k=0; k<count/2*2; k+=2) {
  char *temp=words[k]; words[k]=words[k+1]; words[k+1]=temp;
 }
 for (int i=0; i<count; i++) printf("%s\n", words[i]);
 system("PAUSE");
 return 0;
}

12. Написать функцию, которая определяет, являются ли цифры числа n возрастающей последовательностью (вернёт 1 - если да, возрастающая, 0 - нет) (консольный Си, фрагмент)

unsigned int natural (unsigned int n) {
 while (n) {
  int d0=n%10;
  n/=10;
  if (d0<=n%10) return 0;
 }
 return 1;
}

Если нужно "неубывающей последовательностью" - знак "<=" заменяется на "<".

13. Дана строка символов S.
а) Подсчитать наибольшее количество идущих подряд пробелов.
б) Выяснить, верно ли, что в строке S имеются пять идущих подряд букв е. (консольный Си)

#include <stdio.h>
#include <string.h>
 
void main () {
 char s[80];
 puts ("введите строку"); gets(s);
 int i, len=strlen(s), k=0, kmax=0, ke=0, kflag=0;
 for (i=0; i<len; i++) {
  if (s[i]==' ') {
   k++;
   if (k>kmax) kmax=k;
  }
  else k=0;
  if (s[i]=='e') {
   ke++;
   if (ke==5) kflag=1;
  }
  else ke=0;
 }
 printf ("\nМаксимально пробелов подряд: %d",kmax);
 printf ("\n5 букафф e латинских подряд: ");
 printf (kflag?"да":"нет");
 getchar();
}

Здесь
i - номер текущего символа в строке
len - длина строки, полученная стандартной функцией
k - текущее количество идущих подряд пробелов
kmax - максимальное из них
ke - количество подряд идущих букв "е"
kflag - признак того, найдено ли 5 букв "е" подряд

14. Заданы натуральное n > 1 и действительные числа x1, x2, ... , xn. Найти математическое ожидание и дисперсию (консольный Си)

#include <stdio.h>
#include <math.h>
 
void main () {
 const int nmax=100;
 double x[nmax];
 int n,k;
 double m=0,d=0;
 printf ("\Введите n от 2 до %d: ",nmax);
 scanf ("%d",&n);
 for (k=0; k<n; k++) {
  printf ("\nx[%d]=",k+1);
  scanf ("%lf",&x[k]);
  m+=x[k];
 }
 m/=n;
 for (k=0; k<n; k++) d+=pow(x[k]-m,2);
 d=sqrt(d/(n-1));
 printf ("\nM=%lf, D=%lf",m,d);
 fflush(stdin);
 getchar();
}

Формула для дисперсии неудобная, есть лучше. Тест:

Введите n от 2 до 100: 5
x[1]=1
x[2]=2
x[3]=3
x[4]=4
x[5]=5
M=3.000000, D=1.581139

15. Задана последовательность слов. Напечатайте эту же последовательность слов в обратном порядке. (консольный Си)

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main() {
 char s[256],*words[128];
 char *d=" ,.";
 int count=0;
 printf("Enter your string:\n");
 gets (s);
 char *p;
 p=strtok(s, d);
 while (p) {
  words[count] = (char *) malloc (strlen(p)+1);
  strcpy (words[count],p); count++;
  p=strtok(NULL, d);
 }
 for (int i=count-1; i>=0; i--) printf("%s\n", words[i]);
 system("PAUSE");
 return 0;
}
Enter your string:
Mama, pomoi moyu ramu milom,a ruki pomoyami.
pomoyami
ruki
a
milom
ramu
moyu
pomoi
Mama
Нажмите любую клавишу...

Наверное, на предложениях из одного слова будет криво, не проверял.

16. Дано натуральное число n. Написать программу построения матрицы порядка n:

Матрица
Матрица

В полученной матрице обнулить строку с номером k. Вывести на экран исходную и полученную матрицы. (консольный Си)

#include <stdio.h>
#include <stdlib.h>
 
void form_matrix (int **a, int n) {
 int i,j,k;
 for (j=0; j<n; j++) {
  k=n;
  for (i=j; i<n; i++) a[i][j]=k--;
 }
}
 
void print_array (int **a, int n) {
 int i,j;
 for (i=0; i<n; i++) {
  printf ("\n");
  for (j=0; j<n; j++) printf ("%d ",a[i][j]);
 }
}
 
int main () {
 const int n=10;
 int **a;
 int i,j;
 a = (int **) calloc (n, sizeof(int));
 for (i=0; i<n; i++) a[i] = (int *) calloc (n, sizeof(int));
 int k;
 printf ("\nK="); scanf ("%d",&k);
 form_matrix(a,n);
 printf ("Исходная матрица");
 print_array (a,n);
 for (j=0; j<n; j++) a[k][j]=0;
 printf ("\nПреобразованная матрица");
 print_array (a,n);
 getchar();
 return 0;
}

17. Определить количество слагаемых, необходимых для достижения заданной точности ε при исчислении числа "пи" по следующему разложению в ряд: (консольный Си)

разложение числа пи
разложение числа пи
#include <stdio.h>
#include <math.h>
 
int pi (double eps) {
 int k=1; double p=1;
 while (fabs(sqrt(6*p)-M_PI)>eps) {
  k++;
  p+=1/pow(k,2);
 }
 return k;
}
 
int main () {
 double eps=0.001;
 int n=pi(eps);
 printf ("\nN=%d",n);
 getchar ();
 return 0;
}

18. Удаление из массива наиболее часто встречающегося значения. Если таких значений несколько, то выбрать любое из них. Функция должна возвращать количество элементов в получившемся массиве (консольный Си)

#include <stdio.h>
 
int find_most_frequent_item_number (int *a, int n) {
 int i,j,k,l,max=0;
 for (i=0; i<n-1; i++) {
  k=1;
  for (j=i+1; j<n; j++) if (a[i]==a[j]) k++;
  if (k>max) { max=k; l=i; }
 }
 return l;
}
 
void delete_equal_items_by_number (int *a,int &n,int k) {
 int i=0,j,b=a[k];
 while (i<n) {
  if (a[i]==b) {
   for (j=i; j<n-1; j++) a[j]=a[j+1];
   n--; i--;
  }
  i++;
 }
}
 
void print_array (int *a, int n) {
 printf ("\nРазмерность=%d\nЭлементы: ",n);
 for (int i=0; i<n; i++) printf ("%d ",a[i]);
}
 
int main () {
 const int n=10;
 int a[n]={5,2,2,1,2,1,3,3,4,2};
 int k=find_most_frequent_item_number (a,n);
 int n0=n;
 delete_equal_items_by_number (a,n0,k);
 print_array (a,n0);
 getchar();
 return 0;
}

find_most_frequent_item_number (int *a, int n) - ищет номер любого из наиболее часто встречающегося элементов, вернет его номер
delete_equal_items_by_number (int *a,int &n,int k) - удаляет из массива a все элементы, равные a[k]. Массив сжимает "на месте", новую размерность вернет через параметр n, элементы в "хвосте" массива не трогает

Размерность=6
Элементы: 5 1 1 3 3 4

19. Разработать в Turbo Pascal программу перекодировки текстового файла из одной кодировки в другую (между DOS и Windows).

Ниже прикреплён файл архива с исходником в кодировке DOS (файл готов для открытия в Турбо Паскале)

 Перекодировка между DOS и Windows, архив ZIP с программой на Паскале (кодировка файла DOS) (1 Кб)

20. Написать функцию, которая по заданному целочисленному значению возвращает другое целое число, в котором переставлены местами биты в четверках.
Пример работы:
Enter number : 163
You entered: 163 = 0xA3 = 10100011
Result: 92 = 0x5c = 01011100
(консольный Си)

Если число 8-битное хватит и

#include <stdio.h>
 
unsigned char reverce4 (unsigned char n) {
 unsigned char halfs[]={
  0,8,4,12, 2,10,6,14, 1,9,5,13, 3,11,7,15
 };
 return (halfs[(n&0xF0)>>4]<<4)|halfs[n&0x0F];
}
 
int main () {
 int n=163,n2=reverce4 (n);
 printf ("\n%d (%X) -> %d (%X)",n,n,n2,n2);
 getchar();
 return 0;
}
163 (A3) -> 92 (5C)

Тип unsigned char тоже нужен, иначе битовый сдвиг >> будет коряво работать (не заполнять нулями старшие биты, если в старшем бите до сдвига была единица)

21. Написать программу которая выводит таблицу значений функции y=|x+2| (Паскаль)

... при аргументе x, меняющемся от минус бесконечности до бесконечности с шагом "машинный ноль"... а что, должна отлично сработать :)

{$N+}
var x:extended;
begin
 x:=-1.1E4932;
 while x<=1.1E4932 do begin
  writeln (x,' ',abs(x+2));
  x:=x+3.4E-4932;
 end;
end.

На самом деле надо указать нормальные границы изменения x и шаг - как-то так :)

var x,y:real;
begin
 writeln ('x':10,'y':10);
 x:=-1;
 while x<=1.01 do begin
  y:=abs(x+2);
  writeln (x:10:2,y:10:2);
  x:=x+0.1;
 end;
 readln;
end.

"Таблице" обычно не мешает форматирование и заголовок как в этом примере.

22. Написать программу вычисления площади внешней поверхности цилиндра. (Паскаль)

var r,h,s:real;
begin
 write('Радиус цилиндра='); readln (r);
 write('Высота цилиндра='); readln (h);
 s:=2*pi*sqr(r)+2*pi*r*h;
 writeln('Площадь внешней поверхности цилиндра=',s:8:2);
 readln;
end.

23. Построить множество, состоящее из чисел, кратных 7, но не кратных 6 из диапазона 1..255. (Паскаль)

type numbers = set of byte;
var a:numbers;
 b:byte;
begin
 for b:=1 to 255 do if (b mod 7 = 0 ) and (b mod 6 <>0) then a:=a+[b];
 writeln ('Коды значений множества');
 for b:=1 to 255 do if b in a then write (ord(b),' ');
 readln;
end.

24. Дана матрица из 2 столбцов и 10 строк. Первый элемент каждой строки представляет собой общее число студентов, а второй - число отличников в одной из десяти групп. Номер строки соответствует номеру группы на учебном потоке. Отпечатать номера групп, где отличников более 15% и число таких групп. (Паскаль)

const a: array [1..10,1..2] of integer = (
 (20,2), (13,7), (23,2), (11,4), (19,2),
 (25,5), (16,2), (15,3), (21,2), (22,36)
);
var i,k:integer;
begin
 write ('Номера групп ');
 k:=0;
 for i:=1 to 10 do if a[i,2]/a[i,1]>0.15 then begin
  inc(k);
  write (i,' ');
 end;
 writeln;
 write ('Всего групп: ',k);
 readln;
end.
Номера групп 2 4 6 8 10
Всего групп: 5

25. Дан одномерный массив А(2М). Если наибольший элемент этого массива больше 100 и находится в первой половине этого вектора, то все его элементы, расположенные после первого максимума, заменить на минимальный. (консольный Си)

#include <stdio.h>
void main () {
 const int n=6;
 int a[n]={98,99,101,100,101,1};
 int max=a[0],imax=0,min=a[0];
 for (int i=1; i<n; i++) {
  if (a[i]>max) { max=a[i];imax=i; }
  if (a[i]<min) min=a[i];
 }
 if (max>100 && imax<n/2) for (i=imax+1; i<n; i++) a[i]=min;
 for (i=0; i<n; i++) printf ("%d ",a[i]);
 getchar();
}
98 99 101 1 1 1

26. Вывести только те элементы из целочисленного массива, в записи которых все цифры различны. (Visual C++)

#include <iostream>
using namespace std;
 
int main () {
 const int n=10;
 int a[n]={1234, 554, 325, 11, -7, 101, 200, -543, 1111, 202};
 int i,x,digs[5],k,l,j,dif;
 for (i=0; i<n; i++) {
  x=a[i];
  k=0;
  while (x) { digs[k++]=x%10; x/=10; }
  dif=1;
  for (j=0; j<k-1; j++) {
   for (l=j+1; l<k; l++) if (digs[j]==digs[l]) {
    dif=0; break;
   }
   if (!dif) break;
  }
  if (dif) {
   cout << a[i] << " ";
  }
 }
 cin.get();
 return 0;
}

27. Найти количество повторений всех цифр в заданной строке s (консольный Си, фрагмент)

char s[20],c,k[10];
int i;
// ввести строку s
for (i=0; i<10; i++) k[i]=0;
for (i=0; i<strlen(s); i++) {
 c=s[i];
 if (c>='0' && c<='9') k[c-'0']++;
}
for (i=0; i<10; i++) 
 // вывести значение k[i]

Подключается библиотека <string.h> ну или <cstring> смотря какой компилятор.

28. Дан одномерный массив А неупорядоченных целых чисел. Назовем инверсией два стоящих рядом элемента, когда левый элемент больше правого. Из каждой инверсии переписать в массив В меньший элемент. Вывести массив В на экран или выдать сообщение "Массив В пуст". (консольный Си)

#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
#define N 6

int main (void) {
    setlocale(LC_ALL, "rus");
 
    int B[N], A[N]={5,6,2,4,9,3};
    int k=0,i;
 
    for (i=1;i<N;i++) if (A[i-1]>A[i]) B[k++]=A[i];
    if (k==0) printf("Массив пуст\n");
    else for (i=0;i<k;i++) printf("%d\n",B[i]);
 
    system("pause");
    return 0;
}

29. Вводится последовательность из 25 вещественных чисел. Найти порядковый номер того из них, которое наиболее близко к заданному целому. (консольный Си)

#include <stdio.h>
#include <math.h>
 
int main () {
int a=19; //Заданное число
double f,min=1e308;
int n=25,num,nmin;
for (int i=0; i<n; i++) {
 printf ("\nВведите элемент последовательности %d:",i+1);
 scanf ("%lf",&f);
 if (fabs(f-a)<min) { min=fabs(f-a); nmin=i+1; }
}
printf ("\nНомер (с 1)=%d",nmin);
getchar();
return 0;
}

"Наиболее близко", как обычно, есть модуль разности.

Например, числа 3 и 5 одинаково близки к 4, т.к. |4-5|=|4-3|

Вот и ищется минимальный из модулей разности каждого элемента последовательности (f) к заданному числу (a)

А начальное значение минимума min дают заведомо большим (10308), чтоб наверняка хоть раз выполнилось условие модуль_разности<min.

Ну и каждый раз, когда нашли модуль разности ещё меньше, чем помним в переменной min, запоминаем номер элемента, на котором это случилось (nmin).

30. Вычислить на Паскале все возможные комбиации из пяти четырёхзначных символов без повторений. например 5а2и а77ц пи4а 7е3а 96ф3; 5а2и а77ц пи4а 96ф3 7е3а; 5а2и а77ц 96ф3 пи4а 7е3а; и так далее.

const n1=20; {Размерность множества}
var a:array[1..n1] of string[4];
    p:array[1..n1] of integer;
    i,j,k,pp,min,n:integer;
    flag:boolean;
 
function rand_str (len:integer):string;
var i:integer; s:string; x:byte;
begin
 for i:=1 to len do begin
  x:=64+(random(26)+1);
  insert (Chr(x),s,1);
 end;
 rand_str:=s;
end;
 
begin
 writeln ('Введите размерность множества от 1 до ',n1);
 read (n);
 for i:=1 to n do begin
  p[i]:=i; {Заполняем массив индексов}
  a[i]:=rand_str(5) {Массив заполняем случайными строками}
 end;
 for i:=1 to n do write(a[p[i]]:6);{вывод первой перестановки}
 writeln;
 flag:=false;
 repeat
  i:=n;
  repeat
   i:=i-1
  until (p[i]<p[i+1]) or (i=1);{шаг 1 выполнен}
  if p[i]<p[i+1] then begin 
   k:=i; 
   repeat 
    k:=k+1; 
   until (k=n)or(p[k+1]<p[i]); 
   min:=k;
   pp:=p[i];p[i]:=p[min];p[min]:=pp;{шаг 2 выполнен} 
   for k:=i+1 to (i+1+n) div 2 do begin 
    pp:=p[k]; {здесь делает перестановка}
    p[k]:=p[n+i+1-k]; 
    p[n+i+1-k]:=pp 
   end; {шаг 3 выполнен} 
   for i:=1 to n do write(a[p[i]],' '); {вывод перестановки}
   writeln; 
  end 
  else flag:=true 
 until  flag; 
end.

Данные генерируются. Тест:

Введите размерность множества от 1 до 20
4
HFWA LJEI BVBM IUJX
HFWA LJEI IUJX BVBM
HFWA BVBM LJEI IUJX
HFWA BVBM IUJX LJEI
HFWA IUJX LJEI BVBM
HFWA IUJX BVBM LJEI
LJEI HFWA BVBM IUJX
LJEI HFWA IUJX BVBM
LJEI BVBM HFWA IUJX
LJEI BVBM IUJX HFWA
LJEI IUJX HFWA BVBM
LJEI IUJX BVBM HFWA
BVBM HFWA LJEI IUJX
BVBM HFWA IUJX LJEI
BVBM LJEI HFWA IUJX
BVBM LJEI IUJX HFWA
BVBM IUJX HFWA LJEI
BVBM IUJX LJEI HFWA
IUJX HFWA LJEI BVBM
IUJX HFWA BVBM LJEI
IUJX LJEI HFWA BVBM
IUJX LJEI BVBM HFWA
IUJX BVBM HFWA LJEI
IUJX BVBM LJEI HFWA

На тесте ввёл n=4 а не 5, иначе 120 перестановок в консоль не лезут.

31. Ввести 20 чисел в массив. Вводить следующее число нужно только в том случае, если оно не дублирует ни одного уже записанных (если дублирует, программа не должна его считывать, а дать возможность задать заново). (консольный Си)

#include <stdio.h>
 
int in_array (int v, int *a, int n) {
 int r=0;
 for (int i=0; i<n; i++) if (a[i]==v) { r=1; break; }
 return r;
}
 
void array_unique (int *a, int n) {
 for (int i=0; i<n; i++) {
  do {
   printf ("\nВведите a[%d]=",i);
   fflush (stdin);
   scanf ("%d",&a[i]);
   if (!in_array(a[i],a,i)) break;
   else printf ("\nВводи уникальное число, ***!");
  } while (1);
 }
}
 
int main () {
 const int n=20;
 int a[n];
 array_unique (a,n);
 getchar();
 return 0;
}

06.01.2014, 21:50 [15484 просмотра]


теги: c++ программирование список pascal

К этой статье пока нет комментариев, Ваш будет первым