Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
yiper
0 / 0 / 0
Регистрация: 23.02.2016
Сообщений: 2
1

Связанные области

14.11.2018, 21:29. Просмотров 869. Ответов 4

Задача состоит в следующем:
Имеем куб данных, каждая ячейка которого хранит 0 или 1.
Пусть размер куба следующий: Nx элементов по направлению i, Ny по j и Nz по k.
Куб поместить в одномерный массив следующим образом: вначале меняется индекс i, затем j, затем k.

Пусть связанная область это ячейки соприкасающиеся по граням и хранящие 1. Найти количество таких областей и номера содержащихся в них ячеек.

Как это сделать?
Допустим, что мы создаём одномерный массив, тогда количество элементов в нём равно Nx*Ny*Nz.
Нумерация будет такая: 0, 1, 2, ...,(Nx*Ny*Nz - 2), (Nx*Ny*Nz - 1)? Или как, учитывая, что задача требует, чтобы менялись индексы i, j, k?
Правильно ли создать массив array размерности Nx*Ny*Nz, затем нумерация у его элементов будет следующая: array[Ny * Nz * i + Nz * j + k] (код внизу). Если да, то что после этого делать? как пробегать по этому массиву? и как записывать области и содержащиеся в них ячейки?
C#
1
2
3
4
5
6
7
8
9
10
11
12
int Nx = 2;
int Ny = 4;
int Nz = 5;
int[] array = new int[Nx*Ny*Nz];
Random rnd = new Random();
for (int i = 0; i < Nx; i++) {
            for (int j = 0; j < Ny; j++) {
                for (int k = 0; k < Nz; k++) {
                    array[Ny * Nz * i + Nz * j + k] = rnd.Next(2);
                }
            }
        }
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.11.2018, 21:29
Ответы с готовыми решениями:

Определить количество пшеницы, собранное в области, и среднюю урожайность по области
В области 10 районов. Заданы площади, засеваемые пшеницей (в гектарах), и средняя урожайность (в...

Определить, лежит ли точка внутри заштрихованной области, вне заштрихованной области или на ее границе
Составить программу, которая выдает одно из сообщений &quot;Да&quot;, &quot;Нет&quot;, &quot;На границе&quot; в зависимости от...

Определить, лежит ли точка внутри заштрихованной области, вне заштрихованной области или на ее границе
доброе время суток уважаемые форумчане. недавно начали изучать c#. задали написать программы. I....

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

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

4
Storm23
Эксперт .NETАвтор FAQ
7309 / 4302 / 1565
Регистрация: 11.01.2015
Сообщений: 5,552
Записей в блоге: 32
14.11.2018, 22:39 2
Лучший ответ Сообщение было отмечено yiper как решение

Решение

Цитата Сообщение от yiper Посмотреть сообщение
Пусть связанная область это ячейки соприкасающиеся по граням и хранящие 1. Найти количество таких областей и номера содержащихся в них ячеек.
C#
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
88
89
90
91
92
93
using System;
using System.Collections.Generic;
 
namespace ConsoleApplication238
{
    class Program
    {
        const int Nx = 3;
        const int Ny = 4;
        const int Nz = 5;
        static int[] cube = new int[Nx * Ny * Nz];
 
        static Dictionary<int, int> CellIndexToClassNumber = new Dictionary<int, int>();
 
        static void Main(string[] args)
        {
            //заполняем ячейки
            var rnd = new Random(1);
            for (int x = 0; x < Nx; x++)
            for (int y = 0; y < Ny; y++)
            for (int z = 0; z < Nz; z++)
                cube[GetCellIndex(x, y, z)] = rnd.Next(2);
 
            //Класс - группа соединенных между собой ячеек куба.
            //Изначально, каждая ячейка представлена своим собственным классом. Номер класса совпадает с индексом ячейки.
            //Далее перебираем соседние ячейки и объединяем классы. Номер класса в который переходит данный класс заносится в 
            //словарь CellIndexToClassNumber.
 
            //объединяем соседние классы
            for (int x = 0; x < Nx; x++)
            for (int y = 0; y < Ny; y++)
            for (int z = 0; z < Nz; z++)
            if (GetCell(x, y, z) == 1)
            {
                var index = GetCellIndex(x, y, z);
                //ищем 6 соседей
                CheckNeighbor(index, x - 1, y + 0, z + 0);
                CheckNeighbor(index, x + 1, y + 0, z + 0);
                CheckNeighbor(index, x + 0, y - 1, z + 0);
                CheckNeighbor(index, x + 0, y + 1, z + 0);
                CheckNeighbor(index, x + 0, y + 0, z - 1);
                CheckNeighbor(index, x + 0, y + 0, z + 1);
            }
 
            //формируем список классов, каждый из которых является списком индексов ячеек, который входят в класс
            var classes = new Dictionary<int, List<int>>();
            foreach (var pair in CellIndexToClassNumber)
            {
                var cl = pair.Value;//класс, с которым мы соединены
                while (CellIndexToClassNumber.ContainsKey(cl))
                    cl = CellIndexToClassNumber[cl];//ищем конечный класс
 
                if (!classes.ContainsKey(cl))
                {
                    classes[cl] = new List<int>(); //создаем класс, если его еще нет
                    classes[cl].Add(cl);
                }
 
                //добавляем ячейку в класс
                classes[cl].Add(pair.Key);
            }
 
            //выводим список классов и ячейки в них
            foreach (var pair in classes)
            {
                Console.WriteLine("Class {0}, count={1}, cells={2}", pair.Key, pair.Value.Count,string.Join(", ", pair.Value));
            }
 
            Console.ReadLine();
        }
 
        private static void CheckNeighbor(int classIndex, int x, int y, int z)
        {
            if (GetCell(x, y, z) == 0) return;
            var classIndex2 = GetCellIndex(x, y, z);
            if (classIndex < classIndex2)
                CellIndexToClassNumber[classIndex2] = classIndex;//объединяем класс classIndex2 c classIndex
            else
                CellIndexToClassNumber[classIndex] = classIndex2;//объединяем класс classIndex c classIndex2
        }
 
        static int GetCellIndex(int x, int y, int z)
        {
            return Ny * Nz * x + Nz * y + z;
        }
 
        static int GetCell(int x, int y, int z)
        {
            if (x < 0 || x >= Nx || y < 0 || y >= Ny || z < 0 || z >= Nz) return 0;
            return cube[GetCellIndex(x, y, z)];
        }
    }
}
Связанные области
1
yiper
0 / 0 / 0
Регистрация: 23.02.2016
Сообщений: 2
19.11.2018, 17:13  [ТС] 3
Спасибо большое, но смотрите, для имеющегося куба (его вывод наверху скриншота), первой областью (класс 3) должны быть следующие ячейки: 3, 4, 9, 14, 13, 19, 18, 17, 24, 29, 28, 34, 39, 38, 58, 53
0
Миниатюры
Связанные области  
Storm23
Эксперт .NETАвтор FAQ
7309 / 4302 / 1565
Регистрация: 11.01.2015
Сообщений: 5,552
Записей в блоге: 32
19.11.2018, 17:50 4
yiper,
Да, ошибочка вышла.
Вот сейчас все ок:
C#
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Collections.Generic;
 
namespace ConsoleApplication238
{
    class Program
    {
        const int Nx = 3;
        const int Ny = 4;
        const int Nz = 5;
        static int[] cube = new int[Nx * Ny * Nz];
 
        static Dictionary<int, int> CellIndexToClassNumber = new Dictionary<int, int>();
 
        static void Main(string[] args)
        {
            Console.WriteLine("Source:");
 
            //заполняем ячейки
            var rnd = new Random(1);
            for (int x = 0; x < Nx; x++)
            {
                for (int y = 0; y < Ny; y++)
                {
                    for (int z = 0; z < Nz; z++)
                    {
                        var v = cube[GetCellIndex(x, y, z)] = rnd.Next(2);
                        Console.Write(v);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
 
            //Класс - группа соединенных между собой ячеек куба.
            //Изначально, каждая ячейка представлена своим собственным классом. Номер класса совпадает с индексом ячейки.
            //Далее перебираем соседние ячейки и объединяем классы. Номер класса в который переходит данный класс заносится в 
            //словарь CellIndexToClassNumber.
 
            //объединаем соседние классы
            for (int x = 0; x < Nx; x++)
            for (int y = 0; y < Ny; y++)
            for (int z = 0; z < Nz; z++)
            if (GetCell(x, y, z) == 1)
            {
                var index = GetCellIndex(x, y, z);
                //find 6 neighbors
                CheckNeighbor(index, x - 1, y + 0, z + 0);
                CheckNeighbor(index, x + 1, y + 0, z + 0);
                CheckNeighbor(index, x + 0, y - 1, z + 0);
                CheckNeighbor(index, x + 0, y + 1, z + 0);
                CheckNeighbor(index, x + 0, y + 0, z - 1);
                CheckNeighbor(index, x + 0, y + 0, z + 1);
            }
 
            //формируем список классов, каждый из которых является списком индексов ячеек, который входят в класс
            var classes = new Dictionary<int, List<int>>();
            foreach (var pair in CellIndexToClassNumber)
            {
                var cl =  GetEndClass(pair.Value);//класс, с которым мы соединены
 
                if (!classes.ContainsKey(cl))
                {
                    classes[cl] = new List<int>(); //создаем класс, если его еще нет
                    classes[cl].Add(cl);
                }
 
                //добавляем ячейку в класс
                classes[cl].Add(pair.Key);
            }
 
            //выводим список классов и ячейки в них
            foreach (var pair in classes)
            {
                Console.WriteLine("Class {0}, count={1}, cells={2}", pair.Key, pair.Value.Count,string.Join(", ", pair.Value));
                DrawMatrices(pair.Value);
            }
 
            Console.ReadLine();
        }
 
        private static void DrawMatrices(List<int> cl)
        {
            for (int x = 0; x < Nx; x++)
            {
                for (int y = 0; y < Ny; y++)
                {
                    for (int z = 0; z < Nz; z++)
                    {
                        var index = GetCellIndex(x, y, z);
                        var v = cl.Contains(index) ? 1 : 0;
                        Console.Write(v);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
        }
 
        private static void CheckNeighbor(int classIndex, int x, int y, int z)
        {
            if (GetCell(x, y, z) == 0) return;
            var classIndex2 = GetCellIndex(x, y, z);
 
            var endClass1 = GetEndClass(classIndex);
            var endClass2 = GetEndClass(classIndex2);
 
            if (endClass1 < endClass2)
                CellIndexToClassNumber[classIndex2] = endClass1;//объединяем класс classIndex2 c endClass1
            else
                CellIndexToClassNumber[classIndex] = endClass2;//объединяем класс classIndex c endClass2
        }
 
        /// <summary>
        /// Ищем конечный класс, к которому мы присоеденены
        /// </summary>
        static int GetEndClass(int cl)
        {
            while (CellIndexToClassNumber.ContainsKey(cl))
                cl = CellIndexToClassNumber[cl];//ищем конечный класс
 
            return cl;
        }
 
        static int GetCellIndex(int x, int y, int z)
        {
            return Ny * Nz * x + Nz * y + z;
        }
 
        static int GetCell(int x, int y, int z)
        {
            if (x < 0 || x >= Nx || y < 0 || y >= Ny || z < 0 || z >= Nz) return 0;
            return cube[GetCellIndex(x, y, z)];
        }
    }
}
Связанные области
0
Storm23
Эксперт .NETАвтор FAQ
7309 / 4302 / 1565
Регистрация: 11.01.2015
Сообщений: 5,552
Записей в блоге: 32
19.11.2018, 18:09 5
А вот так еще лучше:
C#
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections.Generic;
 
namespace ConsoleApplication238
{
    class Program
    {
        const int Nx = 3;
        const int Ny = 4;
        const int Nz = 5;
        static int[] cube = new int[Nx * Ny * Nz];
 
        static Dictionary<int, int> CellIndexToClassNumber = new Dictionary<int, int>();
 
        static void Main(string[] args)
        {
            Console.WriteLine("Source:");
 
            //заполняем ячейки
            var rnd = new Random(1);
            for (int x = 0; x < Nx; x++)
            {
                for (int y = 0; y < Ny; y++)
                {
                    for (int z = 0; z < Nz; z++)
                    {
                        var v = cube[GetCellIndex(x, y, z)] = rnd.Next(2);
                        Console.Write(v);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
 
            //Класс - группа соединенных между собой ячеек куба.
            //Изначально, каждая ячейка представлена своим собственным классом. Номер класса совпадает с индексом ячейки.
            //Далее перебираем соседние ячейки и объединяем классы. Номер класса в который переходит данный класс заносится в 
            //словарь CellIndexToClassNumber.
 
            //объединаем соседние классы
            for (int x = 0; x < Nx; x++)
            for (int y = 0; y < Ny; y++)
            for (int z = 0; z < Nz; z++)
            if (GetCell(x, y, z) == 1)
            {
                var index = GetCellIndex(x, y, z);
                //find 6 neighbors
                CheckNeighbor(index, x - 1, y + 0, z + 0);
                CheckNeighbor(index, x + 1, y + 0, z + 0);
                CheckNeighbor(index, x + 0, y - 1, z + 0);
                CheckNeighbor(index, x + 0, y + 1, z + 0);
                CheckNeighbor(index, x + 0, y + 0, z - 1);
                CheckNeighbor(index, x + 0, y + 0, z + 1);
            }
 
            //формируем список классов, каждый из которых является списком индексов ячеек, который входят в класс
            var classes = new Dictionary<int, List<int>>();
            foreach (var pair in CellIndexToClassNumber)
            {
                var cl =  GetEndClass(pair.Value);//класс, с которым мы соединены
 
                if (!classes.ContainsKey(cl))
                {
                    classes[cl] = new List<int>(); //создаем класс, если его еще нет
                    classes[cl].Add(cl);
                }
 
                //добавляем ячейку в класс
                classes[cl].Add(pair.Key);
            }
 
            //выводим список классов и ячейки в них
            foreach (var pair in classes)
            {
                Console.WriteLine("Class {0}, count={1}, cells={2}", pair.Key, pair.Value.Count,string.Join(", ", pair.Value));
                DrawMatrices(pair.Value);
            }
 
            Console.ReadLine();
        }
 
        private static void DrawMatrices(List<int> cl)
        {
            for (int x = 0; x < Nx; x++)
            {
                for (int y = 0; y < Ny; y++)
                {
                    for (int z = 0; z < Nz; z++)
                    {
                        var index = GetCellIndex(x, y, z);
                        var v = cl.Contains(index) ? 1 : 0;
                        Console.Write(v);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
        }
 
        private static void CheckNeighbor(int classIndex, int x, int y, int z)
        {
            if (GetCell(x, y, z) == 0) return;
            var classIndex2 = GetCellIndex(x, y, z);
 
            var endClass1 = GetEndClass(classIndex);
            var endClass2 = GetEndClass(classIndex2);
 
            if (endClass1 < endClass2)
            {
                CellIndexToClassNumber[classIndex2] = endClass1; //объединяем класс classIndex2 c endClass1
                if (endClass2 != endClass1)
                    CellIndexToClassNumber[endClass2] = endClass1; //объединяем класс endClass2 c endClass1
            }
            else
            {
                CellIndexToClassNumber[classIndex] = endClass2; //объединяем класс classIndex c endClass2
                if (endClass1 != endClass2)
                    CellIndexToClassNumber[endClass1] = endClass2; //объединяем класс endClass1 c endClass2
            }
        }
 
        /// <summary>
        /// Ищем конечный класс, к которому мы присоеденены
        /// </summary>
        static int GetEndClass(int cl)
        {
            while (CellIndexToClassNumber.ContainsKey(cl))
                cl = CellIndexToClassNumber[cl];//ищем конечный класс
 
            return cl;
        }
 
        static int GetCellIndex(int x, int y, int z)
        {
            return Ny * Nz * x + Nz * y + z;
        }
 
        static int GetCell(int x, int y, int z)
        {
            if (x < 0 || x >= Nx || y < 0 || y >= Ny || z < 0 || z >= Nz) return 0;
            return cube[GetCellIndex(x, y, z)];
        }
    }
}
0
19.11.2018, 18:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2018, 18:09

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

Лежит ли точка внутри заштрихованной области, вне заштрихованной области или на ее границе
Ребят, будьте добры помогите пожалуйста с программой на с#:)Вот само задание:. Дана точка на...

Лежит ли точка внутри заштрихованной области, вне заштрихованной области или на ее границе
Погогите составить программу, которая выдает одно из сообщений «Да», «Нет», «На границе» в...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru