Форум программистов, компьютерный форум, киберфорум
Java для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
7 / 17 / 0
Регистрация: 30.09.2021
Сообщений: 232

Заполнять массив случайными числами, пока сумма граничных и внутренних элементов не будет равна

26.10.2021, 14:27. Показов 3847. Ответов 47
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задание "Написать класс, который заполняет двумерный массив размером 5х4 случайными положительными двузначными числами до тех пор, пока сумма граничных элементов(1 и последняя строка и 1 и последний столбец) не будет равна сумме внутренних".
Мой вариант повис. Что в нём не так?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class Deliteli {
  public static Scanner sc = new Scanner(System.in);
public static void main(String []args){   
    int n=5;
    int m=4; 
    int sumv=0,sumg=0,sum=0;
    int [][]arr=new int[n][m];
    build(arr,n,m);
    write(arr);
    System.out.println();
    sumG(arr,n,m,sumv,sumg,sum);
}
public static void sumG(int[][]arr, int n,int m,int sumv,int sumg,int sum){
    for(int i=0;i<n;i++){ 
        for(int j=0;j<m;j++){
         sum+=arr[i][j];    
        }
    }
    for(int i=1;i<n-1;i++){ 
        for(int j=1;j<m-1;j++){      
        sumv+=arr[i][j]; 
        }
        }
        sumg=sum-sumv;
  System.out.println("sumg="+sumg+",sumv="+sumv+",sum="+sum);
 while(sumv!=sumg){
    build(arr,n,m);
    if(sumv==sumg)
    write(arr);
}
}
public static int[][]build(int[][]arr, int n,int m){
for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){      
arr[i][j]=(int)(10+Math.random()*(99-10+1));
        }
}
    return arr;
}
public static void write(int[][]arr){
   for(int i=0;i<arr.length;i++){
      for(int j=0;j<arr[i].length;j++){
          if(arr[i][j]/10!=0)
          System.out.print(arr[i][j]+" ");
          else
           System.out.print(arr[i][j]+"  ");   
}
   System.out.println();
        }
}
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.10.2021, 14:27
Ответы с готовыми решениями:

Заполнить массив случайными числами от 1 до 9 до тех пор пока их четная сумма не станет больше заданного М
2)Заполнить массив случайными числами от 1 до 9 до тех пор пока их четная сумма не станет больше заранее заданного числа М. Вывести сумму и...

Создать типизированный файл. Заполнять его числами до тех пор пока не будет введена цифра 5
помогите пожалуйста!

Реализовать приложение, позволяющее заполнять двумерный массив случайными числами
Реализовать приложение, позволяющее заполнять двумерный массив случайными числами. Осуществить перестановку значений элементов массива...

47
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
27.10.2021, 12:37
Тут много неопределенностей в задании.
1) массив 5х4 т.е. фиксированной длины
2)не указано что есть сумма внутренних элнменотов. Если граничные это строка, то внутренние это квадрат3х2??? Т.е. для внутренних считать скмму квадрата?
3) заполняем до тех пор... т.е. есть матрица 5х4 и ее еще можно недозаполнить?
4) при таких условиях вероятность положительного исхода в сравнентт сумм практически рпвна нулю
0
 Аватар для Aviz__
2755 / 2062 / 509
Регистрация: 17.02.2014
Сообщений: 9,491
27.10.2021, 13:01
Цитата Сообщение от darkduke Посмотреть сообщение
квадрат3х2
это не может быть квадрат, т.к. квадрат 3х3 или 2х2.
Цитата Сообщение от Sollita Посмотреть сообщение
Что в нём не так?
то, как ты представила условие. ты уверена, что это не перемешивание изначально заполненного 5х4 массива определенными числами?
0
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
27.10.2021, 13:52
Цитата Сообщение от Aviz__ Посмотреть сообщение
это не может быть квадрат, т.к. квадрат 3х3 или 2х2.
Ну прямоугольник, сути вопроса не меняет. Слишком расплывчатая постановка. Нужно больше уточнений.
Судя по коду программы матрица заполняется именно рандомными числами.
А значит вероятность что будет счастье крайне мала. По поводу зависания программы все просто:
Java
1
2
3
4
5
while(sumv!=sumg){
    build(arr,n,m);
    if(sumv==sumg)
    write(arr);
}
Соответственно если один раз sumv!=sumg, то тогда мы оттуда никогда не выйдем, т.к. build лишь перестраивает матрицу, но ничего не считает и переменные не модифицирует.
0
7 / 17 / 0
Регистрация: 30.09.2021
Сообщений: 232
27.10.2021, 15:01  [ТС]
darkduke, вот полный текст задачи "1. Напишите метод, который получает в качестве параметров дву­мерный массив целых чисел и возвращает сумму всех элементов на границах массива ( первая и последняя строка, первый и по­следний столбец).
2. Напишите метод, который получает в качестве параметров дву­мерный массив целых чисел и возвращает сумму всех его внут­ренних элементов ( т.е. элементов, не находящихся на границах).
3. Напишите класс, который заполняет двумерный массив размером 5x4 случайными положительными двузначными числами до тех пор, пока сумма граничных элементов не окажется равной сумме внутренних". Первые два пункта я сделала, остался третий.
Может, попробовать вставить циклы for в while? Но тогда я вообще запутаюсь.
Или вынести цикл while в новый метод, а внутри него дать ссылку на метод sumG?

Добавлено через 4 минуты
Aviz__, уверена. Я выше привела скопированное условие задачи.
Я понимаю, что нужно сделать.
Нужно заполнить массив случайными числами, посчитать и сравнить суммы внешних и внутренних элементов. Если они не равны, всё начать с начала и продолжать до тех пор, пока сумма внешних элементов не будет равна сумме внутренних элементов. Но как это сделать, я не знаю.
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
27.10.2021, 15:35
while (sumBorder(array) != sumInternal(array)) {
array = getRandomArray();
}
1
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
27.10.2021, 15:44
Вот накидал общую схему, но как и сказал крутится эта штука может очень долго т.к. шанс выйти тут вероятностный ибо рандом, есть рандом....

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MyApp {
  public static void main() {
      int [][] m  =  new int[5][4];
      while (true) {
           build(m);
           if (calcSumInnerElements(m) == calcSumOuterElements(m)) {
                printArray(m);
                brake;
           }
      }
  }
  public static int calcSumInnerElements(int [][] m) {
  //...
  }
  public static int calcSumOuterElements(int [][] m) {
  //...
  }
  public static build(int [][] m) {
  //....
  }
  public static void printArray(int [][] m) {
    //....
  }
}
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38193 / 21126 / 4309
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
27.10.2021, 18:54
Вот подсчет суммы граничных элементов любого прямоугольного массива:


Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main
{
    public static int sumBounder(int [][] arr)
    {
        int rows = arr.length;
        int cols = arr[0].length;
        int s=0;
        
        for (int i=0; i<cols; i++)    s+=arr[0][i]+arr[rows-1][i];
        for (int j=1; j<rows-1; j++ ) s+=arr[j][0]+arr[j][cols-1];
        
        return s;
        
    }
    
    public static void main(String[] args) {
        int [][] x ={{1,2,3},{4,5,6},{1,1,1}};
        int g = sumBounder(x);
        System.out.println(g);
    }
}
0
7 / 17 / 0
Регистрация: 30.09.2021
Сообщений: 232
27.10.2021, 19:12  [ТС]
Catstail, мне кажется, что мой способ нахождения суммы граничных элементов проще и красивее
И мой вопрос был не о том. Думаю, что мне на него чуть выше ответили. Завтра проверю.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38193 / 21126 / 4309
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
27.10.2021, 19:17
Цитата Сообщение от Sollita Посмотреть сообщение
мне кажется, что мой способ нахождения суммы граничных элементов проще и красивее
- это который sumG? Об да! 4 цикла (2 по 2 вложенных), конечно, проще, чем просто два цикла. И Ваш код оформлен "красиво". А уж про организацию я вообще падаю ниц - это уже музыка сфер...
0
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
27.10.2021, 19:33
Цитата Сообщение от Catstail Посмотреть сообщение
- это который sumG? Об да! 4 цикла (2 по 2 вложенных), конечно, проще, чем просто два цикла. И Ваш код оформлен "красиво". А уж про организацию я вообще падаю ниц - это уже музыка сфер...
Ну харе уже маленьких избивать, если на то пошло то можно эту сумму подсчитать в 1 цикл
1
7 / 17 / 0
Регистрация: 30.09.2021
Сообщений: 232
27.10.2021, 20:42  [ТС]
Catstail, я в 8 строчках нахожу 3 неизвестных, а Вы в пяти строчках - одно. К тому же мой код интуитивно понятен, а над Вашим нужно думать
А "красиво" относится не к оформлению кода, а к ходу мысли Красиво я увернулась от необходимости считать ячейки.
0
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
27.10.2021, 21:26
Лучший ответ Сообщение было отмечено Sollita как решение

Решение

кстати о подсчетах, если убрать пункты 1 и 2, то можно оптимизировать подсчет заменив условие:
Java
1
if (calcSumInnerElements(m) == calcSumOuterElements(m)) {
на
Java
1
2
if (currentElementsBalance(m) == 0) {
....
где currentElementsBalance() будет такой:
Java
1
2
3
4
5
6
7
8
9
10
11
12
public static int currentElementsBalance(int [][] m) {
    int sBalance = 0;
    for (int i = 0; i < m.length; i++) {
        for (int j = 0; j < m[i].length; j++) {
            if (i == 0 || i == m.length - 1 || j == 0 || j == m[i].length - 1) {
                   sBalance -= m[i][j];
            } else {
                   sBalance += m[i][j];
            }
        }
    }
}

И кстати можно пойти дальше и интегрировать туда build вставив перед if в 5 строке m[i][j] = ....
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38193 / 21126 / 4309
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
28.10.2021, 08:38
darkduke, да, можно и в один цикл. Можно и совсем без циклов. (см. ниже) Но этот подход будет ненаглядным.

Цитата Сообщение от Sollita Посмотреть сообщение
К тому же мой код интуитивно понятен, а над Вашим нужно думать
- интуитивно понятен он Вам, поскольку Вы его писали. Мой код устроен проще (и по размеру он меньше).

Цитата Сообщение от darkduke Посмотреть сообщение
Ну харе уже маленьких избивать
- ни о каком "избиении" речь не идет. Просто свободный обмен мнениями. Лично я никому ничего не навязываю. Но когда я вижу чье-то решение, явно лучшее, чем моё, то я реагирую адекватно (разбираю, осмысливаю, благодарю). А Sollita идет другим путем: она будет изо всех сил доказывать, что овёс кушает лошадей, а Каспийское море впадает в Волгу.

Sollita, суммировать можно по-разному, но у Вас в 25-й строке замечательного кода стоит печать. Это, разумеется, Ваше право, но элементарные соображения декомпозиции (из которых потом выросло ООП) предлагают составлять функции так, чтобы функция (метод) выполняла ровно одно действие (в данном случае - считала сумму граничных элементов). А вот что делать с этой суммой - пусть решает тот, кто будет эту функцию вызывать (может напечатать, может в файл записать, может по сети отослать куда-то). А теперь не соглашайтесь изо всех сил!

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class Main
{
    // Решение с циклами
 
    public static int sumBounder(int [][] arr)
    {
        int rows = arr.length;
        int cols = arr[0].length;
        int s=0;
        
        for (int i=0; i<cols; i++)    s+=arr[0][i]+arr[rows-1][i];   // суммирование верхней и нижней строки
        for (int j=1; j<rows-1; j++ ) s+=arr[j][0]+arr[j][cols-1]; // суммирование первой и последней колонки (без первых и последних элементов)
        
        return s;
        
    }
 
    // Решение без циклов (рекурсия)
 
    public static int sb(int [][] arr, int i, int j, int s)
    {
        int rows = arr.length;
        int cols = arr[0].length;
        
        if (j<cols)
        {
            return sb(arr,i,j+1,s+arr[0][j]+arr[rows-1][j]); // суммирование верхней и нижней строки
        }
        if (i<rows-1)
        {
            return sb(arr,i+1,j,s+arr[i][0]+arr[i][cols-1]); // суммирование первой и последней колонки (без первых и последних элементов)
        }
 
        return s;        
        
    }
    
    public static void main(String[] args) {
        int [][] x ={{1,2,3},{4,5,6},{1,1,1}};
 
        int g1 = sumBounder(x);  // Проверка первого
        System.out.println(g1);
 
        int g2 = sb(x,1,0,0);        // Проверка второго
        System.out.println(g2);
 
    }
}
Не утверждаю, что так нужно поступать в реальности, но, как видите, так тоже можно.
1
 Аватар для Aviz__
2755 / 2062 / 509
Регистрация: 17.02.2014
Сообщений: 9,491
28.10.2021, 12:53
Лучший ответ Сообщение было отмечено Sollita как решение

Решение

Sollita, держи, проверяй. не думал, что так быстро находит решение:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.util.Arrays;
import java.util.Random;
 
public class Helper {
 
    public static void main(String[] args) {
        ProblemSums2DimArrayElements aSomeProblem = new ProblemSums2DimArrayElements(5, 4);
        aSomeProblem.findSpecificFill();
    }
 
}
 
class ProblemSums2DimArrayElements {
    private static long MAX_POS_SUM_INNER_ELEM = 0;
    private static Random rndGen = new Random(System.currentTimeMillis());
    private final int[][] intArray;
 
    ProblemSums2DimArrayElements(int row, int col) {
        this.intArray = new int[row][col];
        MAX_POS_SUM_INNER_ELEM = (long) (row - 2) * (col - 2) * 99;
    }
 
    void fillArrayRandomValues() {
        for (int i = 0; i < intArray.length; i++) {
            for (int j = 0; j < intArray[0].length; j++) {
                intArray[i][j] = rndGen.nextInt(90) + 10;
            }
        }
    }
 
    long getBorderElementSum() {
        long sum = 0;
        // sum of rows
        for (int j = 0; j < intArray[0].length; j++) {
            sum += intArray[0][j];
            sum += intArray[intArray.length - 1][j];
        }
        if (sum > MAX_POS_SUM_INNER_ELEM) return -1;
 
        // sum of columns
        for (int[] ints : intArray) {
            sum += ints[0];
            sum += ints[intArray[0].length - 1];
        }
        return sum > MAX_POS_SUM_INNER_ELEM ? -1 : sum;
    }
 
    long getInnerElementSum() {
        long sum = 0;
        for (int i = 1; i < intArray.length - 1; i++) {
            for (int j = 1; j < intArray[0].length - 1; j++) {
                sum += intArray[i][j];
            }
        }
        return sum;
    }
 
    void findSpecificFill(){
        do {
            fillArrayRandomValues();
        } while (getInnerElementSum() != getBorderElementSum());
        printArray();
    }
 
    void printArray(){
        for (int[] row : intArray)
            System.out.println(Arrays.toString(row));
    }
}
одно из решений

[12, 55, 12, 10]
[26, 41, 63, 27]
[14, 80, 57, 18]
[42, 86, 95, 21]
[12, 49, 28, 31]
1
7 / 17 / 0
Регистрация: 30.09.2021
Сообщений: 232
28.10.2021, 14:56  [ТС]
darkduke, Спасибо, работает и мой метод, и Ваш. Правда, окончательного результата я не дождалась
Я немного адаптировала Ваш вариант, чтобы можно было контролировать промежуточные результаты, но все лишние System.out.println можно убрать при желании.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class SimpleArray {
            public static Scanner sc = new Scanner(System.in);
     public static void main(String[] args) {
        int n=4;
    int m=4; 
    int [][]arr=new int[n][m];
    arr=build(arr);
    write(arr); 
        while (currentElementsBalance(arr) != 0) {
    arr=build(arr);        
   if (currentElementsBalance(arr) == 0) {
    write(arr);
                break;
     }
   System.out.println();
     }
     }
public static int currentElementsBalance(int[][]arr){
    int sBalance1 = 0,sBalance2 = 0,sBalance=0;
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[i].length; j++) {
            if (i == 0 || i == arr.length - 1 || j == 0 || j == arr[i].length - 1) {
                   sBalance1 -= arr[i][j];   
            } else {
                   sBalance2 += arr[i][j];
            }
        }
    } 
    sBalance=sBalance1+sBalance2;
     System.out.println("Граничная сумма="+sBalance1);
     System.out.println("Внутренняя сумма="+sBalance2);     
if (sBalance==0) 
   System.out.println("Граничная и внутренняя суммы равны"); 
else
   System.out.println("Граничная и внутренняя суммы не равны");
return sBalance;
}
public static int[][]build(int[][]arr){
for(int i=0;i<arr.length;i++){
    for(int j=0;j<arr[i].length;j++){      
arr[i][j]=(int)(10+Math.random()*(100-10+1));
        }
}
    return arr;
}
public static void write(int[][]arr){
   for(int i=0;i<arr.length;i++){
      for(int j=0;j<arr[i].length;j++){
          if(arr[i][j]/10!=0)
          System.out.print(arr[i][j]+" ");
          else
           System.out.print(arr[i][j]+"  ");   
}
   System.out.println();
        }
}
}
Добавлено через 17 минут
Catstail, 1. Мой код интуитивно понятен, потому что даже шестиклассник догадается из площади вычесть меньшую площадь, чтобы получать остаток Я просто вытащила дырку и получился квадратный бублик
2. Если Вы напишете код, который вычисляет и граничную и внутреннюю сумму, что мне требуется по заданию, а не только граничную, как у Вас, то увидите, что мой код лучше.
3. За вариант с рекурсией спасибо, не потому, что он лучше, а потому, что я и не предполагала, что такое возможно. Мне раньше рекурсия нигде не попадалась. Изучу.
Была бы благодарна, если бы Вы объяснили этот код. Я поняла, что метод ссылается сам на себя. Но как в нём возможно применить три return?
0
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
28.10.2021, 14:58
Цитата Сообщение от Sollita Посмотреть сообщение
darkduke, Спасибо, работает и мой метод, и Ваш. Правда, окончательного результата я не дождалась
Я немного адаптировала Ваш вариант, чтобы можно было контролировать промежуточные результаты, но все лишние System.out.println можно убрать при желании.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class SimpleArray {
            public static Scanner sc = new Scanner(System.in);
     public static void main(String[] args) {
        int n=4;
    int m=4; 
    int [][]arr=new int[n][m];
    arr=build(arr);
    write(arr); 
        while (currentElementsBalance(arr) != 0) {
    arr=build(arr);        
   if (currentElementsBalance(arr) == 0) {
    write(arr);
                break;
     }
   System.out.println();
     }
     }
public static int currentElementsBalance(int[][]arr){
    int sBalance1 = 0,sBalance2 = 0,sBalance=0;
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[i].length; j++) {
            if (i == 0 || i == arr.length - 1 || j == 0 || j == arr[i].length - 1) {
                   sBalance1 -= arr[i][j];   
            } else {
                   sBalance2 += arr[i][j];
            }
        }
    } 
    sBalance=sBalance1+sBalance2;
     System.out.println("Граничная сумма="+sBalance1);
     System.out.println("Внутренняя сумма="+sBalance2);     
if (sBalance==0) 
   System.out.println("Граничная и внутренняя суммы равны"); 
else
   System.out.println("Граничная и внутренняя суммы не равны");
return sBalance;
}
public static int[][]build(int[][]arr){
for(int i=0;i<arr.length;i++){
    for(int j=0;j<arr[i].length;j++){      
arr[i][j]=(int)(10+Math.random()*(100-10+1));
        }
}
    return arr;
}
public static void write(int[][]arr){
   for(int i=0;i<arr.length;i++){
      for(int j=0;j<arr[i].length;j++){
          if(arr[i][j]/10!=0)
          System.out.print(arr[i][j]+" ");
          else
           System.out.print(arr[i][j]+"  ");   
}
   System.out.println();
        }
}
}
Добавлено через 17 минут
Catstail, 1. Мой код интуитивно понятен, потому что даже шестиклассник догадается из площади вычесть меньшую площадь, чтобы получать остаток Я просто вытащила дырку и получился квадратный бублик
2. Если Вы напишете код, который вычисляет и граничную и внутреннюю сумму, что мне требуется по заданию, а не только граничную, как у Вас, то увидите, что мой код лучше.
3. За вариант с рекурсией спасибо, не потому, что он лучше, а потому, что я и не предполагала, что такое возможно. Мне раньше рекурсия нигде не попадалась. Изучу.
Была бы благодарна, если бы Вы объяснили этот код. Я поняла, что метод ссылается сам на себя. Но как в нём возможно применить три return?
Рад что помог, но как и сказал вероятность завершения программы крайне мала т.к. рандом есть рандом
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38193 / 21126 / 4309
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
28.10.2021, 15:12
Шестиклассник - это да, авторитет... Снимаю шляпу! Представьте, что Вы пишете промышленную программу. Матрица у Вас 1000*1000. Для подсчета суммы граничных элементов мой алгоритм сделает ~ 4000 витков цикла. Ваш и шестиклассника - ~ два миллиона витков. При этом почти 2 миллиона сложений будет выполнен зря... Это не все. При таких объемах вычислений еще и погрешность может нарасти. Ваш результат может оказаться менее точным, чем мой.

Если бы Вы попробовали сдать такое решение тестирующей системе, то скорее всего, получили бы результат: "Не проходит по времени".

Уж лучше сделать вот так:

Java
1
2
3
   for (int i=0; i<row; i++)
       for (j=0; j<col; j++)
            if ((i==0) || (j==0)) s+=arr[i][j];
Тоже оптимальностью не блещет - O(n2), но хоть без лишних суммирований вычитаний...

О рекурсии можно поговорить отдельно.
0
14 / 11 / 3
Регистрация: 13.07.2018
Сообщений: 37
28.10.2021, 15:33
Цитата Сообщение от Catstail Посмотреть сообщение
Шестиклассник - это да, авторитет... Снимаю шляпу! Представьте, что Вы пишете промышленную программу. Матрица у Вас 1000*1000. Для подсчета суммы граничных элементов мой алгоритм сделает ~ 4000 витков цикла. Ваш и шестиклассника - ~ два миллиона витков. При этом почти 2 миллиона сложений будет выполнен зря... Это не все. При таких объемах вычислений еще и погрешность может нарасти. Ваш результат может оказаться менее точным, чем мой.

Если бы Вы попробовали сдать такое решение тестирующей системе, то скорее всего, получили бы результат: "Не проходит по времени".

Уж лучше сделать вот так:

Java
1
2
3
   for (int i=0; i<row; i++)
       for (j=0; j<col; j++)
            if ((i==0) || (j==0)) s+=arr[i][j];
Тоже оптимальностью не блещет - O(n2), но хоть без лишних суммирований вычитаний...

О рекурсии можно поговорить отдельно.
Ну тестирующая система это отдельный разговор, но что касается асимптотики то вы должны знать, что O(2N2) тоже самое что и O(N2), но тут на самом деле не N2, а m*n и как не крути ни верти быстрее чем m*n вы ее никогда не решите, по любому вам нужно прочитать все элементы. А рекурсия - зло: плодить стек на стеке выполняя лонг джампы это отвратительно, хотя код иногда при ней выглядит проще и читабельный. Но если речь зайдет о деревьях, динамическом программировании где код четко ложится на рекуррентные соотношения, то конечно отвратительная рекурсия становится прекрасной)))
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38193 / 21126 / 4309
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
28.10.2021, 16:13
Я рассматривал только вопрос о вычислении граничных элементов. Если решать задачу в исходной постановке то суммирование всей матрицы выполнить придется - но всего один раз. Я бы поступил так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class Main
{
 
    public static int rnd(int a, int b)
    {
        return a+(int)(Math.random()*(b-a+1));
    }
 
    public static void fillArray(int [][] arr, int cols, int rows)
    {
        for (int i=0; i<rows; i++)
            for (int j=0; j<cols; j++)
                arr[i][j]=rnd(0,3);
    }
 
 
    public static void main(String[] args) 
    {
    
       Scanner inp=new Scanner(System.in);
       
       int [] [] arr = new int [5][5];
       int sg,si,ir,ic,step,sn,sv,k;
       
       fillArray(arr,5,5);
       
       // Первый расчет 
       
       sg=si=0;
       
       for (int i=0; i<5; i++)
           for (int j=0; j<5; j++)
               if ((i==0) || (j==0) || (i==4) || (j==4))
                  sg+=arr[i][j];
               else
                  si+=arr[i][j];
 
       // Главный цикл
 
       step=1;
 
       while (true)
       {
 
           System.out.println("Шаг "+step);
           System.out.println("Матрица:");
           
           for (int i=0; i<5; i++)
           {
               for (int j=0; j<5; j++) System.out.printf("%3d",arr[i][j]);
               System.out.println();       
           }
           System.out.println("Сумма граничных= "+sg);
           System.out.println("Сумма внутренних= "+si);         
 
           if (sg==si)
           {
               System.out.println("Ура, свершилось!!!");
               break;
           }
           
           ir=rnd(0,4);
           ic=rnd(0,4);
           
           System.out.println(ir+" "+ic);
           
           sv=arr[ir][ic];
           sn=rnd(0,3);
           
           if (ir==0 || ic==0 || ir==4 || ic==4)
           {
              sg=sg-sv;
              sg=sg+sn;
           }
           else
           {
              si=si-sv;
              si=si+sn;
           }
            
           arr[ir][ic]=sn;      
           step++;                 
 
       }
 
    }
}

И вот результат:

Кликните здесь для просмотра всего текста

.....
Шаг 698
Матрица:
0 0 3 1 3
3 3 2 0 0
0 3 1 3 1
3 1 1 3 1
2 0 0 2 0
Сумма граничных= 19
Сумма внутренних= 17
0 2
Шаг 699
Матрица:
0 0 2 1 3
3 3 2 0 0
0 3 1 3 1
3 1 1 3 1
2 0 0 2 0
Сумма граничных= 18
Сумма внутренних= 17
2 2
Шаг 700
Матрица:
0 0 2 1 3
3 3 2 0 0
0 3 2 3 1
3 1 1 3 1
2 0 0 2 0
Сумма граничных= 18
Сумма внутренних= 18
Ура, свершилось!!!



Добавлено через 8 минут
Цитата Сообщение от darkduke Посмотреть сообщение
Ну тестирующая система это отдельный разговор, но что касается асимптотики то вы должны знать, что O(2N2) тоже самое что и O(N2), но тут на самом деле не N2, а m*n и как не крути ни верти быстрее чем m*n вы ее никогда не решите
- если говорить о полной задаче, то асимптотика, да O(n*m). Но если говорить только о вычислении суммы граничных - то O(n+m) (Я выше оговорил это условие).

Да, каюсь - подсчет суммы только граничных за время O(n*m) у меня вкралась ошибка - поторопился. Правильно, разумеется, вот так:


Java
1
2
3
for (int i=0; i<row; i++)
       for (j=0; j<col; j++)
            if ((i==0) || (j==0) || (i==row-1) || (j==col-1) s+=arr[i][j];
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.10.2021, 16:13
Помогаю со студенческими работами здесь

Заполните массив случайными числами в интервале [0,1000] и найдите количество элементов, старшая цифра которых равна 8
3. Заполните массив случайными числами в интервале и найдите количество элементов, старшая цифра которых равна 8. Простым школьным языком.

Создать программу, которая имела бы возможность заполнять массив случайными числами!
Найти три последовательных элемента в массиве (20х15), сумма которых максимальна

Заполнения одномерного массива случайными числами, в которую передается какой массив надо заполнять
Вот программа: program mestami; var a:array of integer; i,m,p,poz:integer; begin for i:=1 to 20 do begin ...

Сложный перебор чисел, до тех пор пока их сумма не будет равна данной
Числа которые мы перебираем - sum_light, числа которые находим - sum_big цель кода: перебирать числа из sum_light и суммировать до...

Заполнить двумерный массив случайными числами из интервала и и найти в какой строке сумма элементов наибольшая
Заполнить двумерный массив N x N случайными числами из интервала и найти в какой строке сумма элементов является наибольшей. Сумму...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru