Двумерные массивы

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
lazio
Сообщения: 6
Зарегистрирован: 25 дек 2007, 17:02

Двумерные массивы

Сообщение lazio » 25 дек 2007, 17:12

Добрый день.
Возникла проблема в написании программы с двумерными массивами.
Суть задачи в том, что задается размер матрицы и задается номер строки и номер столбца элемента. Этому элементу присваивается 1, окаймляющим его элементам - 2, вокруг них - 3 и так далее. Размер массива 15 на 15.

Проблема в превышении размера массива, в результате чего программа циклится.
Надеюсь на вашу помощь.

Вот вариант работы который я написал.

Код: Выделить всё

#include <stdio.h>
    #include <math.h>
    #include <conio.h>
   void  main (void)
{
   int  s,p,i,n,m,j,g,k,h,z;
      int A[15][15];
  clrscr();

  do
 {
  printf("Vvedite kolichestvo strok: ");
  scanf("%d", &s);

  printf("Vvedite kolichestvo stolbcov: ");
  scanf("%d", &p);

  if( s>14 || p>14 || s<0 || p<0)
  printf("Vvedite chislo ot 0 do 14!\n\n");
 }
   while (s>14 || p>14 ||s<0 || p<0);

  do
 {
  printf("Vvedite nomer stroki elementa: ");
  scanf("%d", &n);

  printf("Vvedite nomer stolbca elementa: ");
  scanf("%d", &m);

  if (n>s || m>p)
  printf("Oshibka vvoda dannyh!\n\n");
 }
  while (n>s || m>p);

  A[n][m]=1;

   for(i=1;i<=s;i++)
  {
	     printf("\n");
     for(j=1;j<=p;j++)
    {
	for (k=1; k<8; k++)
	for (z=1;z<8;z++)
       {

	 	  A[n+k][m+k]=k+1;
	  A[n+k][m-k]=k+1;
	  A[n-k][m+k]=k+1;
	  A[n-k][m-k]=k+1;
	  A[n+k-z][m+k]=k+1;
	  A[n+k][m+k-z]=k+1;
	  A[n-k+z][m-k]=k+1;
	  A[n-k][m-k+z]=k+1;
	 } 
       

      printf("%d  ", A[i][j]);
    }
  }
   getch();
}

Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Re: Двумерные массивы

Сообщение Romeo » 25 дек 2007, 20:16

Просто перед присваиванием проверяй оба участвующих в выражении индекса на то, что они входят в интервал [0, 14] и присваивание выполняй только в том случае, если оба индекса в правильных границах. Ничего хитрого, просто много if'ов.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

lazio
Сообщения: 6
Зарегистрирован: 25 дек 2007, 17:02

Re: Двумерные массивы

Сообщение lazio » 15 янв 2008, 14:33

Все это конечно хорошо, но даже при наличии ифов при некоторых крайних случаях программа впадает в ступор...я хочу сказать что предложеный мной алгоритм решения скорее всего не верный (кусок что ниже). Над этой скорее всего простейшей задачей я бьюсь уже не 1 неделю, идей иссякли, может кто нибудь предложит другой алгоритм ) я очень прошу

Код: Выделить всё

for (k=1; k<8; k++)
	for (z=1;z<8;z++)
       {

	 	  A[n+k][m+k]=k+1;
	  A[n+k][m-k]=k+1;
	  A[n-k][m+k]=k+1;
	  A[n-k][m-k]=k+1;
	  A[n+k-z][m+k]=k+1;
	  A[n+k][m+k-z]=k+1;
	  A[n-k+z][m-k]=k+1;
	  A[n-k][m-k+z]=k+1;
	 } 

Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Re: Двумерные массивы

Сообщение Romeo » 15 янв 2008, 15:05

А вот так? :)

Код: Выделить всё

  for (i = 0; i < s; ++i)
  {
	 for (j = 0; j < p; ++j)
	 {
		int di = abs(n - i);
		int dj = abs(m - j);
		A[i][j] = di > dj ? di : dj;
		printf("%d ", A[i][j]);
	 }
	 printf("\n");
  }

Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Re: Двумерные массивы

Сообщение Romeo » 15 янв 2008, 15:20

По поводу этой задачи скажу слово. Был у нас в университете преподаватель. Он любил говорить, что любую задачу можно решить двумя способами.

Первый путь - это сесть и решать тем способом, который первым пришёл в голову. А второй путь - сеть у придумывать действетельно лёгкий, быстрый и красивый приём, который позволит решить задачу в кратчшайшие сроки, прилагая минимум усилий. И у того, и у того подхода есть свои плюсы и минусы.

Пойдя по первому пути можно зайти в тупик и потратить кучу времени на то, чтобы из этого тупика выйти. Вполне возможно, что выйти и не получится. И всё равно придётся возвращаться к истокам и искать другой способ решения задачи.

Второй путь сложнее. Пойдя по нему рискуешь не придумать простого способа вообще и останешься даже без теоретического шанса на решение.

Господа, глаголил после этого преподаватель, научитесь находить золотую середину. Не бросайтесь на решение задачи очертя голову, рискуете потерять больше времени, чем подумав всего несколько минут перед тем, как начать решение. Но и не сидите в раздумьях вечность, а то сдадите лист конрольной работы кристально чистым.

Мораль этой басни проста и очевидна. Думайте, перед тем, как начать что-либо делать. И не будет вам цены, как специалистам. Думайте, господин lazio, думайте :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

Ответить