Программа является ли матрица магическим квадратом

Есть целая квадратная матрица. Нужно определить является ли эта матрица магическим квадратом, т.е. такой матрицой в которой суммы элементов во всех строках и столбцах одинаковы. Мой код:

import random p=0 n=int(input(‘Введите четное число: ‘)) matrix=[[random.randrange(10) for i in range(n)] for j in range(n)] for elem in matrix: print(elem) for k in range(n): #Проверяю равны ли суммы всех элементов строк между собой for l in range(k+1,n): if sum(matrix[k])==sum(matrix[l]): p+=1 #если предыдущая строка равна по сумме элементов следущей, то переменную p увеличиваю на единицу, чтобы потом если p==n (если p равняется кол-ву строк, то потом проверять на сумму элементов по столбцам матрицы)

Но как проверить равны ли суммы элементов столбцов матрицы? Подскажите пожалуйста.

Отслеживать

задан 27 ноя 2018 в 18:18

299 2 2 золотых знака 8 8 серебряных знаков 18 18 бронзовых знаков

Источник: ru.stackoverflow.com

Решение задачи «Симметричная ли матрица»

Проверить, является ли матрица магическим квадратом — C#

написать программу, которая проверяет, является ли введенная с клавиатуры квадратная матрица «магическим квадратом». подскажите каким более удобным способом можно проверить матрицу. вот мой код , но он не работает . исправьте пожайлуста мой код и напишите свою версию.

Console.WriteLine(«Введите размер матрицы «); Console.Write(«-> «); int n = int.Parse(Console.ReadLine()); int x = n; int z = n; int[,] mas; mas = new int[x, z]; for (int i = 0; i < mas.Length; i++) < for (int j = 0; j < mas.Length; j++) < Console.WriteLine(«Заполняем ряды матрицы. введите число и нажмите «); Console.Write(«-> «); mas[i,j] = int.Parse(Console.ReadLine()); if(j == 2) < break; >> if (i == 2) < break; >> for (int i = 0; i < mas.Length; i++) < for (int j = 0; j < mas.Length; j++) < Console.Write(mas[i,j] + » «); if (j == 2) < break; >> Console.WriteLine(); if (i == 2) < break; >> int sum = 0; int sum2 = 0; int sum3 = 0; int sum4 = 0; int sum5 = 0; for (int i = 0; i < mas.Length; i++) < for (int j = 0; j < mas.Length; j++) < sum += mas[i, j]; if(j == 2) < for ( i = 1; i < mas.Length; i++) < for ( j = 0; j < mas.Length; j++) < sum2 += mas[i, j]; if(j == 2) < for ( i = 2; i < mas.Length; i++) < for ( j = 0; j < mas.Length; j++) < sum3 += mas[i, j]; if(j == 2) < for ( j = 0; j < mas.Length; j++) < for ( i = 0; i < mas.Length; i++) < sum4 += mas[j,i]; if(i == 2) < break; >> > > > > > > > > > > Console.WriteLine(» «);

Читайте также:
Подключить партнерскую программу ВК

Код к задаче: «Проверить, является ли матрица магическим квадратом»

Листинг программы

10 14 Определение, является ли матрица магическим квадратом


using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 < class Program < static void Main(string[] args) < int[,] arr = < < 2, 7, 6 >, < 9, 5, 1 >, < 4, 3, 8 >>; Console.WriteLine(IsMagic(arr)); Console.ReadKey(); > static bool IsMagic(int[,] arr) < int n = arr.GetLength(0); if (n != arr.GetLength(1)) return false; int sum = n * (n * n + 1) / 2; for (int i = 0; i < n; i++)< int sumRow = 0; int sumCol = 0; for (int j = 0; j < n; j++)< sumRow += arr[i,j]; sumCol += arr[j,i]; >if (sumRow != sum || sumCol != sum) return false; > int sumDiag1 = 0; int sumDiag2 = 0; for (int i = 0; i < n; i++) < sumDiag1 += arr[i,i]; sumDiag2 += arr[n — 1 — i, i]; >if (sumDiag1 != sum || sumDiag2 != sum) return false; return true; > > >

Источник: studassistent.ru

Проверьте, является ли моя матрица магическим квадратом

А теперь я хочу проверить, является ли это «магическим квадратом». Это означает, что суммы всех строк, столбцов и наклонных линий соответственно равны (здесь со значением 15).

Поэтому, поскольку я хочу сделать это максимально эффективно, и мне нужно сначала распечатать матрицу, я хочу выполнить все проверки значений в одной и той же функции:

void printmatrix(int *mat, int dimension) < int i, j, rowscount, colcount; int firstvalue = 0; int ismagicsquaere = 0; for (i = 0; i < dimension; i++) < rowscount = 0; for (j = 0; j < dimension; j++) < int num = *(mat + i * dimension + j); if (i == 0) firstvalue += num; else rowscount += num; printf(«%dt», num); >if (rowscount != firstvalue) ismagicsquaere = 0; printf(«nn»); >

В настоящее время моя функция проверяет только значение строк. Интересно, можно ли также проверить столбцы и косые линии?

user2976232 29 ноя ’17 в 14:32 2017-11-29 14:32
2017-11-29 14:32

4 ответа

Делать все внутри вложенного for петли это интересная проблема.

Единственная небольшая задача заключалась в том, чтобы также вычислить суммы столбцов, так как при написании циклов кажется, что сначала потребуется массив [размерность].

Однако небольшой трюк помогает. Эта строка, чтобы получить значение строки

int rownum = *(mat + i * dimension + j);

Может также использоваться для получения значения col путем инвертирования i а также j

int colnum = *(mat + j * dimension + i);

Позволяет также суммировать столбцы в одном месте (матрица — квадрат!)

void printmatrix(int *mat, int dimension) < int i, j; int magic=1; // default to «is magic» int d1=0,d2=0,refcount=0; // diag1, diag2 for (i = 0 ; i < dimension; i++) < int rowcount = 0; int colcount = 0; for (j = 0; j < dimension; j++) < int num = *(mat + i * dimension + j); rowcount += num; // row sum if (i == j) d1 += num; // diag1 sum if (i == dimension-j-1) d2 += num; // diag2 sum // row to col . colcount += *(mat + j * dimension + i); // col sum >if (!i) refcount = rowcount; // first rowcount is reference else if (refcount != rowcount) magic = 0; if (refcount != colcount) magic = 0; > if (d1 != refcount || d2 != refcount) magic = 0; printf(«Is Magic: %sn», magic ? «Yes»:»No»); >
user338904 29 ноя ’17 в 15:16 2017-11-29 15:16
2017-11-29 15:16

Читайте также:
Программы it какие бывают

По-видимому, вам придется повторять матрицу 3 раза с 3 отдельными циклами. Я не вижу способа обойти это.

  • Суммируйте первую строку и сохраните этот результат в переменной для дальнейшего использования для сравнения.
  • Суммируйте остальные строки в цикле и сравните с переменной. Если какие-либо суммы не равны, верните false из функции.
  • Второй цикл, проверьте столбцы, сравните с одной и той же переменной, если она неравна, и верните false.
  • Третьи циклы, проверить диагональ, сравнить с той же переменной, если она неравна, вернуть false.

Этот алгоритм, однако, потенциально неэффективен, потому что он очень ветвистый. Что вы можете сделать, чтобы вручную оптимизировать его, так это уменьшить количество веток.

Одна, возможно, более быстрая реализация:

  • Суммируйте все строки, сохраните результаты в массиве результатов. Это дружественно к кешу и будет означать, что массив попадает в кеш данных.
  • Сделайте то же самое с колоннами и диагоналями.
  • Убедитесь, что ваши 3 массива суммы расположены в памяти рядом друг с другом, поместив их в структуру. Это кеш-дружественный. Желательно что-то вроде этого:

typedef union < struct < unsigned int row_sum[3]; unsigned int col_sum[3]; unsigned int dia_sum[2]; >; unsigned int sum [3+3+2]; > sum_t; _Static_assert(sizeof(sum_t) == sizeof(unsigned int[3+3+2]), «Sorry, weird systems are not supported.»);

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

user584518 29 ноя ’17 в 15:07 2017-11-29 15:07
2017-11-29 15:07

Я написал следующий код с целью написать (день) код, который разрабатывает магические квадраты.

В нем хранятся все строки, столбцы и суммы диагоналей в матрице. Цель этой матрицы ( sum[][] ) надо понимать, где магический квадрат не правильный.

Основное вызывает функцию checkAndComputeSums() он вычисляет все суммы и возвращает 1, если данные в магическом квадрате верны, и 0, если не верны.

#include #define DIMS 3 #define COLS DIMS #define ROWS DIMS int checkAndComputeSums(int *s , int *ms, int dim); enum STYPE < SUMROW, SUMCOL, SUMDIAG, //——————- SUMCNT >; int msqr[COLS][ROWS] = < < 8, 1, 6>, < 3, 5, 7>, < 4, 9, 2>>; int sum[DIMS][SUMCNT]; const char * label[SUMCNT] = < «ROWS»,»COLS»,»DIAG» >; int checkAndComputeSums(int *s , int *ms, int dim) < int i,j,ok=1; /* The sum are cleared */ for(i=0;i> for(i=0;i if (s[i*SUMCNT+SUMROW]!=s[SUMROW] || s[i*SUMCNT+SUMCOL]!=s[SUMROW]) ok=0; > if (s[SUMDIAG]!=s[SUMROW] || s[SUMDIAG+SUMCNT]!=s[SUMROW]) ok=0; return ok; > int main(void) < int i,j; i=checkAndComputeSums(sum[0],msqr[0],DIMS); printf(«The check was %sn»,(!i)?»KO»:»OK»); for (j=SUMROW;jputs(«»); > return 0; >
user4769313 29 ноя ’17 в 16:33 2017-11-29 16:33
2017-11-29 16:33

  1. Ваш код глючит, так как вы начинаете с ismagicsquaere = 0 , Но даже если вы начнете с ismagicsquaere = 1 , он все еще глючит, потому что в итерации i = 0 переменная rowscount остается нулевым, так что следующее сравнение всегда приведет к настройке ismagicsquaere = 0 что не то, что вы хотите.
  2. Если вы стремитесь к скорости, вы должны по возможности избегать любого предложения if в цикле, в частности во внутреннем цикле.
  3. Поскольку у вас есть printf во внутреннем цикле, я не буду беспокоиться о скорости вообще, так как эта операция ввода-вывода будет доминировать во время выполнения.
  4. Если вашей целью действительно была быстрая проверка магического квадрата, вам пришлось бы не только удалить вызовы printf, но и вернуть функцию, как только первая проверка не удалась.
Читайте также:
Майл Почта установить программу

Вот мой предложенный код, включая проверки для двух диагоналей. Поскольку я предполагаю, что вам нужно включить печать, я оставил вызовы printf и не добавил досрочного возврата:

void printmatrix(const int *mat, int dimension) < int i, j; int ismagicsquare = 1; int diagonal1 = 0, diagonal2 = 0; for (i = 0; i < dimension; i++) < diagonal1 += mat[i * dimension + i]; diagonal2 += mat[i * dimension + dimension — 1 — i]; >if (diagonal1 != diagonal2) < ismagicsquare = 0; >for (i = 0; i < dimension; i++) < int rowscount = 0; int colscount = 0; for (j = 0; j < dimension; j++) < rowscount += mat[i * dimension + j]; colscount += mat[j * dimension + i]; printf(«%dt», mat[i * dimension + j]); >if (rowscount != diagonal1 || colscount != diagonal1) < ismagicsquare = 0; >printf(«nn»); > printf(«ismagicsquare = %in», ismagicsquare); >

Обратите внимание, что в отношении обращений к памяти и оптимизации кэша, должно быть быстрее всего выполнить проверку суммы строк, как показано, но в тех же двух вложенных циклах приращения сумм по столбцам и их оценка в конце. Таким образом, очень недружелюбный кэш мат доступа к памяти [j * dimension + i] будет полностью удален. Однако этот вид оптимизации имеет смысл только при разработке чистой функции проверки без вызовов printf.

Источник: stackru.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru