Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 8
1

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

26.09.2011, 21:02. Показов 3132. Ответов 9
Метки нет (Все метки)

Доброго времени суток читателям этой темы. Возникло у меня одно затруднение, с которым самому разобраться не получается. Надо написать программу для составления судоку и последующего вывода его на экран. Собственно с этим я справился, точнее просто с вводом чисел в массив, а вот проверку условий организовать не получается. Вот точное задание:
Код
С клавиатуры вводится судоку - матрица Mass[9,9], значения элементов которой принадлежат отрезку [1;9]. Проверить, является ли введённая матрица правильной судоку.
Судоку считается правильной, если в каждом столбце, каждой строке и в каждом квадрате 3х3 нет повторяющихся чисел, т. е. содержатся все числа от 1 до 9.
Вопросы такие:
-Как цикл двумерного массива вернуть на предыдущее действие? Например мне требуется, чтобы числа в массиве были в промежутке [1;9] ввожу их так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
for(s=0;s<9;s=s+3)//определяются координаты квадрата
for(v=0;v<9;v=v+3)
{//задаются цифры в ячейках игрового поля
  for(i=s;i<s+3;i++)
  for(j=v;j<v+3;j++)
  {//вводим число
        printf("введи число\t");
        scanf("%d",&m[i][j]);
    if(m[i][j]>9||m[i][j]<1)
    {//если число больше 9 или меньше 1
        printf("число должно быть в промежутке [1;9]\n");
        ??
....
Как теперь организовать возврат на предыдущее действие цикла чтобы ошибочное число ввести снова?
пока додумался только до такого, но по-моему как то это не правильно.
C
1
2
3
4
5
6
7
8
9
10
 if(m[i][j]>9||m[i][j]<1)
   {//если число больше 9 или меньше 1
        printf("число должно быть в промежутке [1;9]\n");
        if(i%3==0)
       {
        i--;
        j--;
       }
        else
        j--;
И второй вопрос.
-Как организовать сравнение чисел в строке/столбце/квадрате, чтобы нельзя было ввести одинаковые? Как сделать проверку в строке и столбце я примерно понял, а вот как сравнить вводимое число с теми, что уже есть в квадрате я никак не могу понять...
Ну и вот код всей программы.
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
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
void main()
{//вводим данные
setlocale(LC_ALL,"Russian");
int m[9][9]={},i,j,n[9]={0,1,2,3,4,5,6,7,8,9},z=81; //m-массив, i j -ячейки массива, n будет показывать какие числа можно использовать, если введется число, которое уже есть в строке|столбце|квадрате
//z- счетчик оставшихся чисел
int v,s;//координаты квадрата
for(s=0;s<9;s=s+3)//определяются координаты квадрата
for(v=0;v<9;v=v+3)
{//задаются цифры в ячейках игрового поля
  for(i=s;i<s+3;i++)
  for(j=v;j<v+3;j++)
  {//вводим число
        printf("осталось чисел %d\n",z);
        printf("введи число\t");
        scanf("%d",&m[i][j]);
        z--;//счетчик оставшихся чисел
    if(m[i][j]>9||m[i][j]<1)
    {//если число больше 9
        printf("число должно быть в промежутке [1;9]\n");
        //??? - возвращаемся к предыдущему этапу цикла
        z++;//прибавляем колличество оставшихся чисел
    }
   //сравнение чисел
   //???
  }
}
{//вывод на экран
for(i=0;i<9;i++)
    {
    for(j=0;j<9;j++)
    printf("%d ",m[i][j]);
    printf("\n");
    }
 }
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.09.2011, 21:02
Ответы с готовыми решениями:

Написать программу для судоку-цепочки(9*9)
Судоку-цепочки - представляет собой квадрат, состоящий из кружков. Необходимо расставить в кружках...

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

Написать программу для составления плана покупок
Имеется список магазинов каждый из которых имеет свой список продуктов(продукты в некоторых...

Нужно написать программу для составления расписания
всем привет) нужно сделать программу для составления расписания в универе, к примеру для одной -...

9
539 / 444 / 162
Регистрация: 10.12.2009
Сообщений: 1,857
26.09.2011, 21:18 2
проверка корректного ввода такова:
C
1
2
3
4
5
6
do
{
    printf ( "Input number: " );
    scanf  ( "%d", &n );
}
while ( ( n >= 10 ) || ( n <= 0 ) );
А вот с проверкой существования введенного числа и существования такого же в подматрице я бы делала так:
Например, я ввожу число на позиции [ i0, j0 ], то мне нужно проверять квадрат с адресом верхней левой ячейки [ i0 / 3 * 3 + 1, j0 / 3 * 3 + 1 ],
до [ i0 / 3 * 3 + 3, j0 / 3 * 3 + 3 ]... ( считал в уме )
И еще нужно в таком условии проверить выход за границы матрицы.
1
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 8
26.09.2011, 22:03  [ТС] 3
А как быть с поиском одинаковых чисел?
0
539 / 444 / 162
Регистрация: 10.12.2009
Сообщений: 1,857
26.09.2011, 22:18 4
dwags, Так я же выше описал,
Цитата Сообщение от Mиxaил Посмотреть сообщение
А вот с проверкой существования введенного числа и существования такого же в подматрице я бы делала так:...
как один из вариантов.
1
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 8
26.09.2011, 22:23  [ТС] 5
Цитата Сообщение от Mиxaил Посмотреть сообщение
dwags, Так я же выше описал.
Прошу прощения, не увидел.
0
Заблокирован
26.09.2011, 23:51 6
dwags, вы думаете это тривиальная задача? помнится я даже на литературу по судоку наталкивался в поисках алгоритмов решения, но решил это дело оставить до лучших времен.
А как быть с поиском одинаковых чисел?
это как раз самое сложное, точнее сложность в том, чтобы проверить правильность своего числа и его места в матрице. тут мнений столько же, сколько специалистов. эти темы уже неоднократно поднимались разными специалистами, надо искать по сети. В любом случае отталкиваться следует из того что суммы всех строк равны суммам всех столбцов. т.е. имеем систему девяти линейных уравнений, зависимую от себя же таким образом, что единственно верным будет такое решение, при котором поворот матрицы на 90 градусов против часовой стрелки не даст тот же результат что и начальная матрица (под результатом понимается сумма, или коэффициент элементов строки и для каждой строки он неизменяем). когда есть такой результат, и при повороте (не транспонировании, а именно повороте) матрицы то же самое, это и есть единственно верное решение судоку.

Добавлено через 22 минуты
да, забыл. суммы девяти матриц 3х3 тоже должны быть равны константе

Добавлено через 31 минуту
я немного тут написал лишнего, сейчас покурю и мат формулой выражу свою мысль.

Добавлено через 20 минут
имеем матрицу 9х9 вида:
https://www.cyberforum.ru/cgi-bin/latex.cgi?\left(<br />
\begin{array}<br />
a_{i = 1,j = 1} & \ldots & a_{1,9} \\<br />
\vdots & \ddots & \vdots  \\<br />
a_{9,1} & \ldots & a_{9, 9} \\<br />
\end{array}<br />
\right)
так вот для проверки необходимо чтобы
https://www.cyberforum.ru/cgi-bin/latex.cgi?\sum_{j = 1}^{j = 9} a_{1, j} = \sum_{j = 1}^{j = 9} a_{2, j} = ... = \sum_{j = 1}^{j = 9} a_{9, j} = 45 также и со столбцами
https://www.cyberforum.ru/cgi-bin/latex.cgi?\sum_{i = 1}^{i = 9} a_{i, 1} = \sum_{i = 1}^{i = 9} a_{i, 2} = ... = \sum_{i = 1}^{i = 9} a_{i, 9} = 45
так же и суммы всех элементов каждой из 9 матриц 3х3 равнялись 45.
1
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 8
27.09.2011, 01:31  [ТС] 7
alkagolik, ох блин, это надо будет сейчас разбираться, благо вся ночь впереди). Пока что я завис на уровне do/while. Как сделать, чтобы при ошибочном вводе появлялось сообщение об ошибке? Что бы я не делал, оно появляется в случае правильного ввода (однако числа вносятся в массив как положено). Подскажите, что я делаю не так?
C
1
2
3
4
5
6
7
8
9
10
int m[3][3],i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
    do{
    printf("vvedi chislo\n");
    scanf("%d",&m[i][j]);}
    while(m[i][j]>0||m[i][j]<9);
    printf("ne podhodit\n");
}
0
Заблокирован
27.09.2011, 02:01 8
Цитата Сообщение от dwags Посмотреть сообщение
Как сделать, чтобы при ошибочном вводе появлялось сообщение об ошибке?
в смысле? что такое ошибочный ввод?

Добавлено через 26 минут
я вот вижу в задании есть только требование проверки матрицы на принадлежность sudoku, так это просто сейчас организуем. C99 поддерживается? компилятор какой?
0
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 8
27.09.2011, 02:31  [ТС] 9
Цитата Сообщение от alkagolik Посмотреть сообщение
в смысле? что такое ошибочный ввод
Чтобы когда я например ввел число 10, появилось сообщение о том, что число большое, и этот элемент массива надо было ввести снова. Вывести сообщение об ошибке я могу, но при этом ошибочное число все равно записывается в массив..

Добавлено через 26 минут
я вот вижу в задании есть только требование проверки матрицы на принадлежность sudoku, так это просто сейчас организуем. C99 поддерживается? компилятор какой?
компилятор Code:Blocks под кубунтой.
зы: я тут пока что придумывал как организовать сравнение чисел, пока такое получилось
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
      for(q=1;q<=i;q++)
      {
          if(m[i-q][j]==m[i][j])
          {
          printf("такое число уже есть в столбце\n");
          //??? возврат к предыдущей точке.
          //z++;
          }
      }
      for(w=1;w<=j;w++)
    {
        if(m[i][j-w]==m[i][j])
        {
            printf("такое число есть в строке\n");
            //??? возврат к предыдущей точке
            //z++
        }
    }
  for(q=s+1;q<=s+3;q++)
  for(w=v+1;w<=v+3;w++)
  {
      if(m[q][w]==m[i][j])
      {
      printf("такое число есть в квадрате\n");
      }
  }
В общем проверка строки и столбца работает, но опять же я не знаю как заставить программу повторить ввод ошибочного числа.
С квадратом труднее получается, тут надо как то использовать переменные, которые отвечают за положение квадрата 3х3, у меня это s и v. Вот как их использовать, я пока тоже не придумал
0
Заблокирован
27.09.2011, 05:02 10
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Цитата Сообщение от dwags Посмотреть сообщение
Чтобы когда я например ввел число 10, появилось сообщение о том, что число большое, и этот элемент массива надо было ввести снова. Вывести сообщение об ошибке я могу, но при этом ошибочное число все равно записывается в массив..
можно так
C
1
2
3
4
5
6
7
8
9
10
11
do{
/*заполняем*/
 
array[iter_str][iter_collum]
      
      if(chislo < 1 || chislo >9){
            --iter_collum;
            printf("blablabla");
      }
 
}while (iter_collum != SIZE_ARRAY - 1);
так же можно поступить и с строковым итератором. короче вот я накидал рабочий код для проверки матрицы 9х9 на принадлежность судоку
код
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
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<errno.h>
#include<string.h>
 
#define arr_size    9
#define arr_sum    45
 
_Bool check_sudoku_elements (int arr[][arr_size]);
 
int main(){
    srand(time(NULL));
    int i = 0, k = 0, sum = 0, tmp_i, tmp_k;
    _Bool check = 1, iter = 1;
    int arr_mat[arr_size][arr_size];
 
    for(i = 0; i!= arr_size; ++i)
        for(k = 0; k!= arr_size; ++k)
            arr_mat[i][k] = rand() % 9 + 1;
    /* провереная судоку */
    /*int arr_mat[arr_size][arr_size] = {
    {3, 5, 8, 1, 6, 4, 9, 2, 7},
    {2, 1, 9, 7, 5, 3, 8, 6, 4},
    {4, 7, 6, 9, 8, 2, 3, 1, 5},
    {6, 8, 2, 5, 9, 7, 1, 4, 3},
    {1, 4, 7, 2, 3, 8, 5, 9, 6},
    {5, 9, 3, 4, 1, 6, 2, 7, 8},
    {9, 3, 5, 6, 7, 1, 4, 8, 2},
    {8, 6, 4, 3, 2, 9, 7, 5, 1},
    {7, 2, 1, 8, 4, 5, 6, 3, 9},
    };*/
 
    for(i = 0; i!= arr_size; ++i){
        for(k = 0; k!= arr_size; ++k)
            printf("%d ", arr_mat[i][k]);
        printf("\n");
    }
 
    for(i = 0; i != arr_size; ++i){
        
        sum = 0;
        if(check){
            for(k = 0; k != arr_size; ++k)
                sum += arr_mat[i][k];
            
            printf("%d\n", sum);
 
            if(sum != arr_sum)
                check = 0;
 
        }
        else break;
    }
 
    if(!check);
    else{
        for(i = 0; i != arr_size; ++i){
            
            sum = 0;
            
            if(check){
                for(k = 0; k != arr_size; ++k)
                    sum += arr_mat[k][i];
                
                printf(" %d\n", sum);
                
                if(sum != arr_sum)
                    check = 0;
            }
            else break;
        }
    }
 
    if(!check);
    else{
        for (i = 0; i < arr_size; i += 3)
            for(k = 0; k < arr_size; k += 3){
 
                sum = 0;
 
                if(check){
                    for (tmp_i = i; tmp_i < i + 3; ++tmp_i)
                        for(tmp_k = k; tmp_k < k + 3; ++tmp_k)
                            sum += arr_mat[tmp_i][tmp_k];
                        
                        printf("  %d\n", sum);
 
                        if(sum != arr_sum)
                            check = 0;
                }
                else break;
            }
    }
 
    if(check)
        printf("эта матрица есть судоку\n");
    else
        printf("эта матрица не есть судоку\n");
 
    return 0;
}

результат работы с матрицей судоку и не судоку
Код
chertopolox@chertopolox-Ubuntu:~/documents/projects/system/bin/Debug$ ./system 
3 5 8 1 6 4 9 2 7 
2 1 9 7 5 3 8 6 4 
4 7 6 9 8 2 3 1 5 
6 8 2 5 9 7 1 4 3 
1 4 7 2 3 8 5 9 6 
5 9 3 4 1 6 2 7 8 
9 3 5 6 7 1 4 8 2 
8 6 4 3 2 9 7 5 1 
7 2 1 8 4 5 6 3 9 
45
45
45
45
45
45
45
45
45
 45
 45
 45
 45
 45
 45
 45
 45
 45
  45
  45
  45
  45
  45
  45
  45
  45
  45
эта матрица есть судоку
chertopolox@chertopolox-Ubuntu:~/documents/projects/system/bin/Debug$ ./system 
8 6 8 6 7 9 5 6 2 
5 7 5 8 9 6 3 1 2 
3 6 3 1 7 7 3 1 8 
1 8 1 9 6 4 8 9 1 
7 4 6 7 7 4 9 5 3 
5 5 4 4 5 7 6 3 2 
3 4 9 1 4 8 8 2 2 
3 9 2 3 4 3 7 1 9 
1 1 2 1 3 4 2 7 6 
57
эта матрица не есть судоку


Добавлено через 10 минут
в принципе твоя задача выполнена, но если интересно именно решение судоку загляни сюда

Добавлено через 20 минут
кстати для генерации судоку достаточно массива из 9 различных элементов и "операций" сдвига в массиве элементов в такой последовательности построчно:
1. первая строка матрицы и есть массив
2. сдвиг массива на 3 элемента (допустим влево, это важно только для последующих действий)
3. сдвиг массива на 3 элемента влево
4. сдвиг массива на 1 элемент вправо
5. сдвиг массива на 3 элемента влево
6. сдвиг массива на 3 элемента влево
7. сдвиг массива на 1 элемент вправо
8. сдвиг массива на 3 элемента влево
9. сдвиг массива на 3 элемента влево

достаточно сгенерировать массив последовательности 1..9 в случайном порядке
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.09.2011, 05:02

Написать программу для составления матрицы, элементами которой будут числа, равные количества цифр в одноименной ячейке в массиве А.
Задан двумерный массив А = (aij), где i = 1,2 ... k, j = 1,2 ... f, элементами которого являются...

Написать программу составления посланий
Написать программу составления посланий. Необходимо предусмотреть ввод двух файлов. В первом...

Написать программу составления списков студентов
Написать программу составления списков студентов В списке можно удалять и добавлять строки,...

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru