Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

osn_progr_final

.pdf
Скачиваний:
37
Добавлен:
12.02.2016
Размер:
3.27 Mб
Скачать

int i,j,g=0,z=0; long cf;

static int a[10],b[10],c[10]; for(i=0,j=48;i<=9,j<=57;i++,j++)

{

a[i]=i;

b[i]=j;

}

for(j=0;j<=100;j++)

{

if(n==0)break;

cf=n%10;

n/=10;

for(i=0;i<10;i++)

{

if(a[i]==cf)

c[z++]=b[i];

}

}

for(z=9;z>=0;z--)

{

if(c[z]!=0)

str[g++]=c[z];

}

str[g]='\0';

}

void main()

{

static char str[80]; long n;

puts("Введіть ціле число n, яке треба перевести в ря-

док:\n"); scanf("%ld",&n); I_TO_B(n,str); puts("\nОсь рядок:\n"); puts(str);

getch();

}

Приклад 3

Написати програму для гри в "Хрестики-Нолики" на полі 3х3 для людини та комп”ютера.

#include<stdio.h>

#include<conio.h>

171

#define ESC 27

int win[24]={0,1,2,3,4,5,6,7, 8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6}; int prov1(int *a)

{

int i,p=0,w[3]; for(i=0;i<8;i++)

{

w[0]=win[i*3];

w[1]=win[i*3+1];

w[2]=win[i*3+2]; if(a[w[0]]==0&&a[w[1]]==0&&a[w[2]]==-1)

{

a[w[2]]=0;

p++;

break;

}

if(a[w[0]]==0&&a[w[1]]==-1&&a[w[2]]==0)

{

a[w[1]]=0;

p++;

break;

}

if(a[w[0]]==-1&&a[w[1]]==0&&a[w[2]]==0)

{

a[w[0]]=0;

p++;

break;

}

}

return p;

}

int prov2(int *a)

{

int i,p=0,w[3]; for(i=0;i<8;i++)

{

w[0]=win[i*3];

w[1]=win[i*3+1];

w[2]=win[i*3+2]; if(a[w[0]]==1&&a[w[1]]==1&&a[w[2]]==-1)

{

a[w[2]]=0;

p++;

break;

172

}

if(a[w[0]]==1&&a[w[1]]==-1&&a[w[2]]==1)

{

a[w[1]]=0;

p++;

break;

}

if(a[w[0]]==-1&&a[w[1]]==1&&a[w[2]]==1)

{

a[w[0]]=0;

p++;

break;

}

}

return p;

}

void main()

{

int i,j,p=0,l,a[9],n; do

{

clrscr(); for(i=0;i<9;i++)a[i]=-1; if(p==0)

{

puts("Комп’ютер ходить першим"); a[4]=0;

for(l=0;l<4;l++)

{

do

{

scanf("%d",&n); if(a[n]!=-1) puts("Клітинка зайнята!");

}while(a[n]!=-1); a[n]=1; if(prov1(a)!=0)

{puts("Ви програли!");break;} if(prov2(a)==0)

{

if(a[0]<0&&a[8]!=1)

a[0]=0;

else if(l==1&&a[1]==1) a[6]=0;

else if(a[2]<0&&a[6]!=1)

173

a[2]=0;

else for(i=0;i<9;i++) if(a[i]<0) {a[i]=0;break;}

}

for(i=0;i<3;i++,putchar('\n'))

for(j=0;j<3;j++) printf("%2d ",a[i*3+j]);

}

}

else

{

puts("Ви ходите першим"); scanf("%d",&n);

a[n]=1;

for(l=0;l<4;l++)

{

if(prov1(a)!=0)

{puts("Ви програли!");break;} if(prov2(a)==0)

{

if(a[4]==-1)a[4]=0;

else if(l==1&&a[0]==1&&a[8]==1||l==1&&a[2]==1&&a[6]==1) a[1]=0;

else if(a[0]<0&&a[8]!=1) a[0]=0;

else if(a[2]<0&&a[6]!=1) a[2]=0;

else for(i=0;i<9;i++) if(a[i]<0) {a[i]=0;break;}

}

for(i=0;i<3;i++,putchar('\n'))

for(j=0;j<3;j++) printf("%2d ",a[i*3+j]); do

{

scanf("%d",&n); if(a[n]!=-1) puts("Клітинка зайнята!");

}while(a[n]!=-1); a[n]=1;

}

}

for(i=0;i<3;i++,putchar('\n'))

174

for(j=0;j<3;j++) printf("%2d ",a[i*3+j]); p=!p;

puts("Знову?(Так-довільна клавиша, Ні-ESC)"); }while(getch()!=ESC);

}

Приклад 4

Із даної на площині множини точок вибрати такі чотири точки, котрі є вершинами випуклого чотирикутника найбільшої площі.

Для розв”язку задачі реалізуємо наступний підхід: будемо переглядати всі можливі четвірки точок , перевіряти, чи є вони вершинами випуклого чотирикутника і знаходити його площу при позитивній перевірці на випуклість. Тоді з усіх таких площ знайдемо максимальну. Для знаходження площі чотирикутника та перевірки його на випуклість будемо використовувати площі трикутників. Очевидно, що площа випуклого чотирикутника завжди дорівнюватиме сумі площ 2 трикутників, що утворюються його сторонами та довільною діагоналлю. Якщо ж чотирикутник не випуклий, то його площа дорівнює сумі площ трикутників лише при певному підборі вершин трикутників. Для знаходження площі трикутника використаємо наступну формулу. Нехай маємо точки з координатами (x1,y1), (x2,y2) та (x3,y3).

Тоді S=1/2| x1y2+ x2y3 +x3y1 -x1y3 –x2y1 –x3y2 |

#include <math.h> #include <stdio.h> #include <conio.h> #include <stdlib.h>

//Структура точки typedef struct

{

float x; float y; } tochka;

//Структура чотирикутника typedef struct

{

tochka t1; tochka t2; tochka t3; tochka t4;

} choturukyt;

175

//Обчислюємо площу трикутника за формулою, записаною вище

float s_tr(tochka t1,tochka t2,tochka t3)

{

return 0.5*fabs(t1.x*t2.y+t2.x*t3.y+t3.x*t1.y- t1.x*t3.y-t2.x*t1.y-t3.x*t2.y);

}

//Обчислюємо площу чотирикутника //Перевіряємо, чи є він випуклим

float s_ch(tochka t1,tochka t2,tochka t3,tochka t4)

{

float s1,s2;

s1=s_tr(t1,t2,t3)+s_tr(t1,t3,t4); s2=s_tr(t2,t3,t4)+s_tr(t1,t2,t4);

if(fabs(s1-s2)/s1<1e-4)return s1; return 0;

}

//Знаходимо найбільшу площу чотирикутника //Методом перебору всіх точок

float poshyk(tochka *A,int n,choturukyt *B)

{

long i,j,k,m; float pre=0,tek;

for(i=0;i<n;i++)

for(j=i+1;j<n;j++)

for(k=j+1;k<n;k++)

for(m=k+1;m<n;m++)

if((tek=s_ch(A[i],A[j],A[k],A[m]))!=0) if(tek>pre)

{

pre=tek; B->t1=A[i]; B->t2=A[j]; B->t3=A[k]; B->t4=A[m];

}

return pre;

}

//Формуємо множину точок

void zapov(tochka *A,long n,long in)

176

{

long i; for(i=0;i<n;i++)

{

A[i].x=in*((float)rand()/(float)32767);

A[i].y=in*((float)rand()/(float)32767);

}

}

void main()

{

choturukyt B; tochka *A; float s; long n,in;

srand(time(NULL));

m1:

clrscr();

printf("Введіть кількість точок (N>4): "); scanf("%ld",&n);

printf("Введіть інтервал(IN>0) від 0 до "); scanf("%ld",&in);

if(n<4 || in<=0)

{

highvideo();

cputs("\nУвага! Помилка при вводі даних!"); normvideo();

getch(); goto m1;

}

if((A=(tochka*)malloc(n*sizeof(tochka)))==NULL)

{

highvideo();

cputs("\nПомилка при виділенні памяті!"); normvideo();

getch();

return;

}

zapov(A,n,in);

clrscr();

if((s=poshyk(A,n,&B))!=0)

{

puts("Точки чотирикутника:");

177

printf("Перша:\t\tx %9.3f\ty %9.3f\n",B.t1.x,B.t1.y); printf("Друга:\t\tx %9.3f\ty %9.3f\n",B.t2.x,B.t2.y); printf("Третя:\t\tx %9.3f\ty %9.3f\n",B.t3.x,B.t3.y); printf("Четверта:\tx %9.3f\ty %9.3f\n",B.t4.x,B.t4.y);

printf("\nПлоща цього чотирикутника: %.3f\n\n",s);

}

else puts("Таких чотирикутників немає!\n");

highvideo();

cputs("Для вихода натисніть Esc..."); putchar('\n');

cputs("Для повтора натисніть Enter..."); normvideo();

free(A);

m2:

switch(getch())

{

case 13: goto m1; case 27: return; default: goto m2;

}

}

Приклад 5. Множення n-вимірних матриць

Розглянемо спочатку, як можна собі уявити множення багатовимірних матриць і як визначити їх добуток. Звичайно, відоме множення звичайних прямокутних чи квадратних матриць за правилом “рядок на стовпчик”. Розглянемо “тривимірні” матриці А та B, елементи яких можуть бути записані, очевидно, у тривимірні масиви . Розглядаючи процес множення за аналогією з двовимірними матрицями, можемо уявити тривимірну матрицю А як вектор-стовпчик двовимірних:

 

 

A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

A2

 

 

 

 

 

 

 

 

 

 

 

 

 

A=

 

 

 

 

B= (B , B ,..., B )

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 2

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

An

 

 

 

 

 

 

 

 

 

 

 

 

Аналогічно матрицю B можна уявити як вектор-рядок двовимірних матриць. Тоді результатом множення є конструкція:

178

C=|| сij || , i 1, n, j 1, n , де cij Ai * B j . Тут Ai * B j є звичайним множенням квадратних матриць і, отже, є двовивірною матрицею. З точки зору представлення даних результат множення тривимірних матриць є, очевидно, чотиривимірною матрицею і представляється чотиривимірним масивом. Тоді за рекурсією можемо визначити добуток довільних n-вимірних матриць A та B, розглядаючи їх відповідно як векторстовпчик та вектор-рядок n-1-вимірних матриць :

 

 

 

 

С=A*B, C=|| сij || , i

1, n

, j

1, n

,

cij Ai * B j ( Ai , Bj –n-1-вимірні матриці).

Тоді добутком n-вимірних матриць буде n+2-вимірна матриця (n>=4).

Відмітимо, що виходячи з способу розміщення в пам”яті n-вимірних масивів в С, будемо притримуватись такої ж домовленості, записуючи n-вимірні масиви у динамічному одновимірному. При цьому, будемо вважати, що для довільної n-вимірної матриці А, що представляється як вектор-стовпчик n-1-вимірних матриць A1 ,A2 ,…An,

 

 

A

 

 

 

 

 

1

 

 

 

A=

 

A2

 

в пам”яті послідовно записуються матриці A1

,A2 ,…An.

 

...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

An

 

 

Відмітимо, що для реалізації відповідної рекурсивної функції нам зручно було б мати матрицю B, у якої б матриці B1 ,B2, …,Bn були розміщені в послідовних блоках пам”яті. Це можна досягти послідовно записуючи в одновимірний масив елементи вихідної матриці з кроком n. Тобто, спочатку записуємо 1-й елемент, потім n-й, 2n-й,3n- й,…, тоді 2-й, 2+n-й,2+2n-й,….Цю процедуру реалізуємо в функції ctranspon (int *a,int n,int m):

long pow(long n,int m) {int i; for(i=0;i<m-1;i++) n*=n;

return n;

}

/*часткове транспонування n-вимірної матриці*/ int* ctranspon (int *a,int n,int m)

179

{

int *rob1,*rob=(int*)malloc(sizeof(int)*pow(n,m)); rob1=rob;

long i,j; int *s;

for (j=0;j<n;j++)

{

s=a++;

for(i=0; i<pow(n,m-1); i++) *rob++=*(s+i*n);

}

return rob1;

}

При реалізації безпосередньо множення матриць будемо записувати результат множення окремих компонент у деякий масив. Причому на вхід функції буде передаватись блоки, що множаться , розмірності та адреса, куди записувати відповідні результати множення (у нашому випадку це **c). Після запису інформації при кожному виклику функції відповідна адреса повинна змінюватись (зсуватись на кількість елементів, що вже записані). Але в С при передачі адреси створюється її локальна копія в функції. Тобто, якщо передати в функцію просто адресу, то ми не зможемо з функції її змінити. Отже, необхідно передавати адресу цієї адреси (або використовувати механізм посилань, реаклізований в С++). Винакає також проблема корректного виділення пам”яті для результату множення. В нашому прикладі це робиться в функції main().

void dobutok(int* a, int* b, int** c, int n, int m)

/*змінна c буде містити результат множення. І, оскільки функція рекурсивно буде змінювати сам вказівник, то будемо передавати в функцію його адресу*/

{

180

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]