/* 10986 C "Sending email" */
/* @BEGIN_OF_SOURCE_CODE */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define PARENT(i) ((i)/2) /* Parent of node i */
#define LEFT(i) (2*(i)) /* Left child of node i */
#define RIGHT(i) ((2*(i))+1) /* Right child of node i */
typedef int (*KEYCMP) (const void *a, const void *b);
typedef void (*DATACPY) (void *dst, const void *src);
typedef void (*DELNODE) (void *n);
typedef void (*PRINTNODE) (const void *n);
typedef struct _binary_heap {
/* Functions to compare, print, copy, delete the elements of this heap */
KEYCMP _keycmpfn;
DATACPY _datacpyfn;
DELNODE _delnodefn;
PRINTNODE _printfn;
char *elements; /* Dynamic array representing the binary heap */
/* elements[] is an array of generic structures of size 'e_size' */
size_t e_size; /* Size of one element */
int nelements; /* Pre-allocated length of array elements[] */
int heap_size; /* Size of the binary heap */
int *indexOf ; /* Get the index in heap of the application object with identifier <id> */
int *handleAt ; /* Instead of moving data in elements[], move pointers to elements[] <i> */
} BINARY_HEAP;
void heap_init(BINARY_HEAP *h, int initial_size, size_t e_size, KEYCMP k, DATACPY d, DELNODE n, PRINTNODE p);
void heap_clean(BINARY_HEAP *h);
void min_heap_insert(BINARY_HEAP *h, int id, const void * n);
void max_heap_insert(BINARY_HEAP *h, int id, const void * n);
void heap_increase_key(BINARY_HEAP *h, int id, const void * n);
void heap_decrease_key(BINARY_HEAP *h, int id, const void * n);
void heap_extract_max(BINARY_HEAP *h, void *min);
void heap_extract_min(BINARY_HEAP *h, void *min);
void heap_maximum(BINARY_HEAP *h, void *min);
void heap_minimum(BINARY_HEAP *h, void *min);
void max_heapify(BINARY_HEAP *h, int i);
void min_heapify(BINARY_HEAP *h, int i);
void heap_swap(BINARY_HEAP *h, int i, int j) {
int t ;
h->indexOf[h->handleAt[i]] = j ;
h->indexOf[h->handleAt[j]] = i ;
t = h->handleAt[i] ;
h->handleAt[i] = h->handleAt[j] ;
h->handleAt[j] = t ;
}
/*
Maintain the MAX-HEAP property.
*/
void max_heapify(BINARY_HEAP *h, int i) {
register int largest, l = LEFT(i), r = RIGHT(i);
largest = (l <= h->heap_size &&
h->_keycmpfn(&h->elements[h->e_size * h->handleAt[l]],
&h->elements[h->e_size * h->handleAt[i]]) > 0) ? l : i;
largest = (r <= h->heap_size &&
h->_keycmpfn(&h->elements[h->e_size * h->handleAt[r]],
&h->elements[h->e_size * h->handleAt[largest]]) > 0) ? r : largest;
if (largest != i) {
heap_swap(h, i, largest);
max_heapify(h, largest);
}
}
/*
Maintain the MIN-HEAP property.
*/
void min_heapify(BINARY_HEAP *h, int i) {
register int smallest, l = LEFT(i), r = RIGHT(i);
smallest = (l <= h->heap_size &&
h->_keycmpfn(&h->elements[h->e_size * h->handleAt[l]],
&h->elements[h->e_size * h->handleAt[i]]) < 0) ? l : i;
smallest = (r <= h->heap_size &&
h->_keycmpfn(&h->elements[h->e_size * h->handleAt[r]],
&h->elements[h->e_size * h->handleAt[smallest]]) < 0) ? r : smallest;
if (smallest != i) {
heap_swap(h, i, smallest);
min_heapify(h, smallest);
}
}
/*
Copies MAX element of the heap to the variable pointed by *max.
*/
void heap_maximum(BINARY_HEAP *h, void *max) {
if (h->heap_size < 1)
return;
else h->_datacpyfn(&max, (void *) &h->elements[h->e_size * h->handleAt[1]]);
}
/*
Copies MIN element of the heap to the variable pointed by *min.
*/
void heap_minimum(BINARY_HEAP *h, void *min) {
heap_maximum(h, min);
}
/*
Removes MAX element from the heap and copies it to *max.
*/
void heap_extract_max(BINARY_HEAP *h, void *min) {
if (h->heap_size < 1)
return;
h->_datacpyfn(min, &h->elements[h->e_size * h->handleAt[1]]);
h->indexOf[h->handleAt[h->heap_size]] = 1 ;
h->indexOf[h->handleAt[1]] = 0 ;
h->handleAt[1] = h->handleAt[h->heap_size] ;
h->handleAt[h->heap_size] = 0 ;
(h->heap_size)--;
max_heapify(h, 1);
}
/*
Removes MIN element from the heap and copies it to *min.
*/
void heap_extract_min(BINARY_HEAP *h, void *min) {
if (h->heap_size < 1)
return;
h->_datacpyfn(min, &h->elements[h->e_size * h->handleAt[1]]);
h->indexOf[h->handleAt[h->heap_size]] = 1 ;
h->indexOf[h->handleAt[1]] = 0 ;
h->handleAt[1] = h->handleAt[h->heap_size] ;
h->handleAt[h->heap_size] = 0 ;
(h->heap_size)--;
min_heapify(h, 1);
}
/*
Increases the key of an element.
*/
void heap_increase_key(BINARY_HEAP *h, int id, const void * n) {
int i ;
/* Get index of the element whose key is to be decreased */
i = h->indexOf[id] ;
if (i < 1 || i > h->heap_size)
return;
while (i > 1 && h->_keycmpfn(&h->elements[h->e_size * h->handleAt[PARENT(i)]], n) < 0) {
h->indexOf[h->handleAt[PARENT(i)]] = i ;
h->handleAt[i] = h->handleAt[PARENT(i)] ;
i = PARENT(i) ;
}
h->handleAt[i] = id ;
h->indexOf[id] = i ;
h->_datacpyfn(&h->elements[h->e_size * id], n);
}
/*
Inserts an element in the maximum binary heap.
Additionally, Increases the size of the underlying array representing the heap if
nelements is already reached.
*/
void max_heap_insert(BINARY_HEAP *h, int id, const void * n) {
int i = ++(h->heap_size);
h->indexOf[id] = i ;
heap_increase_key(h, id, n);
}
/*
* Decreases the key of an element.
*/
void heap_decrease_key(BINARY_HEAP *h, int id, const void * n) {
int i ;
/* Get index of the element whose key is to be decreased */
i = h->indexOf[id] ;
if (i < 1 || i > h->heap_size)
return;
while (i > 1 && h->_keycmpfn(&h->elements[h->e_size * h->handleAt[PARENT(i)]], n) > 0) {
h->indexOf[h->handleAt[PARENT(i)]] = i ;
h->handleAt[i] = h->handleAt[PARENT(i)] ;
i = PARENT(i) ;
}
h->handleAt[i] = id ;
h->indexOf[id] = i ;
h->_datacpyfn(&h->elements[h->e_size * id], n);
}
/*
Inserts an element in the minimum binary heap.
Additionally, Increases the size of the underlying array representing the heap if
nelements is already reached.
*/
void min_heap_insert(BINARY_HEAP *h, int id, const void * n) {
int i = ++(h->heap_size);
h->indexOf[id] = i ;
heap_decrease_key(h, id, n);
}
/*
Cleans a HEAP, removing all the nodes.
*/
void heap_clean(BINARY_HEAP *h) {
int i;
if (h->elements != NULL) {
if (h->_delnodefn)
for (i = 1; i <= h->heap_size; i++)
h->_delnodefn((void *)&h->elements[h->e_size * h->handleAt[i]]) ;
free(h->elements);
h->elements = NULL;
}
/*
printf("\nindex: ") ;
for (i=1; i<=h->nelements; i++) {
printf("%d ", h->indexOf[i]) ;
}
printf("\nhandle: ") ;
for (i=1; i<=h->nelements; i++) {
printf("%d ", h->handleAt[i]) ;
}
*/
h->heap_size = 0;
h->nelements = 0;
h->e_size = 0;
}
/*
Initializes a BINARY_HEAP
*/
void heap_init(BINARY_HEAP *h, int initial_size, size_t e_size, KEYCMP k, DATACPY d, DELNODE n, PRINTNODE p) {
h->_keycmpfn = k;
h->_datacpyfn = d;
h->_delnodefn = n;
h->_printfn = p;
h->heap_size = 0;
h->e_size = e_size;
h->nelements = initial_size;
/* Allocate nelements+1 elements because index in C starts from 1 and
* our heap starts from 1 */
h->elements = (char *) malloc((h->nelements+1) * h->e_size) ;
/* An application object with identifier <id> is stored at index[id] in heap */
h->indexOf = (int *) calloc((h->nelements + 1), sizeof(int));
/* Index <i> in heap points to application object with identifier handle[i] */
h->handleAt = (int *) calloc((h->nelements + 1), sizeof(int));
}
typedef struct _priority_queue {
struct _priority_queue *THIS;
BINARY_HEAP heap;
} PQ, *PQPTR;
void pq_init(PQ *q, size_t initial_size, size_t ele_size, KEYCMP k, DATACPY d, DELNODE n, PRINTNODE p);
void pq_enqueue(PQ *q, const void *n, int id);
void pq_dequeue(PQ *q, void *n);
void pq_peek(PQ *q, void *n);
void pq_decrease_priority(PQ *q, void *n, int id);
void pq_delete(PQ *q);
int is_pq_empty(PQ *q);
void pq_init(PQ *q, size_t initial_size, size_t e_size,
KEYCMP k, DATACPY d, DELNODE n, PRINTNODE p) {
q->THIS = q;
heap_init(&(q->heap), initial_size, e_size, k, d, n, p);
}
int is_pq_empty(PQ *q) {
return (q->heap.heap_size == 0) ? 1 : 0;
}
void pq_enqueue(PQ *q, const void *n, int id) {
min_heap_insert(&(q->heap), id, n);
}
void pq_dequeue(PQ *q, void *min) {
heap_extract_min(&(q->heap), min);
}
void pq_peek(PQ *q, void *min) {
heap_minimum(&(q->heap), min);
}
void pq_delete(PQ *q) {
heap_clean(&(q->heap));
}
void pq_decrease_priority(PQ *q, void *n, int id) {
heap_decrease_key(&(q->heap), id, n) ;
}
enum {undirected=0, directed=1} ;
typedef int weight;
typedef struct _edge {
int v ; /* adjacent node */
weight w ; /* cost of edge (u,v) */
struct _edge *next ; /* pointer to next edge */
} EDGE ;
typedef struct _graph {
EDGE **adj ; /* adjacency list of vertex u */
int nvertices ; /* number of vertices in the graph */
int nedges ; /* number of edge in the graph */
short is_directed ; /* directed or undirected */
int *degree ; /* degree of each vertex */
} GRAPH ;
size_t sizeof_edge ; /* sizeof EDGE */
void graph_init(GRAPH *g, int nvertices, int nedges, short is_directed) ;
void add_edge(GRAPH *g, int u, int v, int cost) ;
void graph_display(GRAPH *g) ;
void graph_clean(GRAPH *g) ;
void graph_init(GRAPH *g, int nvertices, int nedges, short is_directed) {
int i;
sizeof_edge = sizeof (EDGE);
g->nvertices = nvertices;
g->nedges = nedges;
g->is_directed = is_directed;
g->adj = (EDGE **) malloc((g->nvertices+1) * sizeof (EDGE *));
g->degree = (int *) malloc((g->nvertices+1) * sizeof (int));
for (i = 1; i <= g->nvertices; i++) {
g->adj[i] = NULL;
g->degree[i] = 0;
}
}
/*
* Insert an edge (u,v) at the start of the list adj[u].
* Algorithm Design Manual, Skiena., Pg 154.
*/
void __insert_edge(GRAPH *g, int u, int v, int cost, short is_directed) {
EDGE *e;
e = (EDGE *) malloc(sizeof_edge);
e->w = cost;
e->v = v;
e->next = g->adj[u];
g->adj[u] = e;
g->degree[u]++;
/* if the graph is undirected, create another edge (v,u) */
if (!is_directed)
__insert_edge(g, v, u, cost, directed);
}
/*
* Insert an edge (u,v) at the start of the list adj[u].
*/
void add_edge(GRAPH *g, int u, int v, int cost) {
__insert_edge(g, u, v, cost, g->is_directed);
}
void graph_display(GRAPH *g) {
EDGE *e;
int u;
for (u = 1; u <= g->nvertices; u++) {
printf("%d:", u);
e = g->adj[u];
while (e != NULL) {
printf(" (%d,%d)", e->v, e->w);
e = e->next;
}
printf("\n");
}
}
/*
* Destroys the graph.
*/
void graph_clean(GRAPH *g) {
EDGE *e, *k;
int u ;
for (u = 1; u <= g->nvertices; u++) {
e = g->adj[u];
while (e != NULL) {
k = e ;
e = e->next;
free(k) ;
}
g->adj[u] = NULL ;
}
if (g->adj != NULL)
free(g->adj);
if (g->degree != NULL)
free(g->degree);
g->nvertices = g->nedges = g->is_directed = 0;
}
typedef struct _vertex {
int handle; /* identifies the application object (vertex) in heap.
* index 1..nelements */
int v ;
int dist;
} vertex;
int d_key_cmp(const void *a, const void *b) {
if (((vertex *) a)->dist > ((vertex *) b)->dist) return 1;
else if (((vertex *) a)->dist < ((vertex *) b)->dist) return -1;
return 0;
}
void d_data_copy(void *dest, const void *src) {
vertex *n = (vertex *) dest;
n->dist = ((vertex *) src)->dist;
n->v = ((vertex *) src)->v;
}
/*
* Implements Dijkstra Single-Source Shortest Path algorithm.
* The main data structure MIN-PRIORITY-QUEUE used in this algorithm uses a
* MIN-BINARY-HEAP.
*/
void dijkstra(GRAPH *g, int start, int dist[], int path[]) {
PQ pq;
EDGE *e;
int v, u;
vertex n;
/* initialize single source */
pq_init(&pq, g->nvertices, sizeof (vertex), d_key_cmp, d_data_copy, NULL, NULL);
for (v = 1; v <= g->nvertices; v++) {
dist[v] = 1000010;
path[v] = -1;
n.v = v ;
n.dist = dist[v];
pq_enqueue(&pq, &n, v);
}
dist[start] = 0;
dist[start] = 0;
n.v=start ;
n.dist=0 ;
pq_decrease_priority(&pq, &n, start);
while (!is_pq_empty(&pq)) {
pq_dequeue(&pq, &n);
u = n.v ;
e = g->adj[u]; /* for each node (u,v) */
while (e != NULL) {
if (dist[e->v] > dist[u] + e->w) {
dist[e->v] = dist[u] + e->w;
path[e->v] = u;
n.v = e->v ;
n.dist = dist[e->v];
pq_decrease_priority(&pq, &n, n.v);
}
e = e->next;
}
}
pq_delete(&pq) ;
}
int main()
{
GRAPH g;
int n, m, S, T, cases, k, i, u, v, w;
int dist[20001], path[20001] ;
#ifndef ONLINE_JUDGE
freopen("10986.in", "r", stdin) ;
#endif
scanf("%d", &cases);
k = 0;
while (cases--) {
k++;
scanf("%d%d%d%d", &n, &m, &S, &T);
graph_init(&g, n, m, undirected);
for (i = 0; i < m; i++) {
scanf("%d%d%d", &u, &v, &w);
add_edge(&g, u+1, v+1, w);
}
dijkstra(&g, S+1, dist, path) ;
if (dist[T+1]>=1000010)
printf("Case #%d: unreachable\n", k) ;
else
printf("Case #%d: %d\n", k, dist[T+1]) ;
graph_clean(&g) ;
}
return 0;
}
/* @END_OF_SOURCE_CODE */
Code
UVA Online Judge solutions. C, C++, Algorithms.
Pages
Labels
01 Knapsack
(1)
Ad Hoc
(1)
Backtracking
(1)
Binary Search Tree
(1)
bits
(1)
Brute Force
(1)
codelib
(2)
Data Structures
(1)
Dijkstra
(1)
DP
(2)
Graphs
(1)
Heaps
(1)
Joseph
(1)
Maximum 1-D Sum
(1)
Maximum Contiguous Sum
(1)
Primes
(1)
Priority Queues
(1)
Recursion
(1)
Sieve of Atkins
(1)
UVaOJ Vol-102
(1)
UVaOJ Vol-109
(1)
UVaOJ Vol-5
(1)
Tuesday, March 15, 2011
UVa 10986 - Sending email
Labels:
Dijkstra,
Graphs,
Heaps,
Priority Queues,
UVaOJ Vol-109
Sunday, March 6, 2011
UVa 10298 - Power Strings
/* 10298 C "Power Strings" */
/* @BEGIN_OF_SOURCE_CODE */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
char s[1000010] ;
int len, half ;
int find_min_rep_substring(void)
{
int i, j, k, min=len, f ;
char *p ;
for (i=half; i>=2; i--) {
if (len%i!=0)
continue ;
p = s+i ;
f = 1 ;
/* compare k-1 substrings of length i */
for (k=len/i, j=1; j<k; j++) {
if (strncmp(s, p, i)!=0) {
f = 0 ;
break ;
}
p+=i ;
}
if (f) min = i ;
}
return len/min ;
}
int main()
{
int i, j, n, k ;
#ifndef ONLINE_JUDGE
freopen("10298.in", "r", stdin) ;
#endif
while (scanf("%s", s)) {
if (s[0]=='.' && s[1]=='\0')
break ;
len = strlen(s) ;
half = len/2 ;
for (i=0; i<half; i++)
if (s[i]!=s[len-i-1])
break ;
if (i==half && s[0]==s[half]) printf("%d\n", len) ;
/* for odd strings, largest repeating substring would be either of length 1 or len */
else if (len%2) printf("1\n") ;
else printf("%d\n", find_min_rep_substring()) ;
}
return 0;
}
/* @END_OF_SOURCE_CODE */
Saturday, March 5, 2011
UVa 568 - Just the Facts
/* 568 C "Just the Facts" */
/* @BEGIN_OF_SOURCE_CODE */
#include <stdio.h>
#define FACT_UPTO 10001
int n, fact_lnzd[FACT_UPTO] ;
void precompute(void)
{
int i, fact ;
fact_lnzd[0] = fact_lnzd[1] = fact = 1 ;
for (i=2; i<=FACT_UPTO; i++) {
fact = fact * i ;
while (fact%10==0)
fact /= 10 ;
fact = fact%100000 ;
fact_lnzd[i] = fact%10 ;
}
}
int main()
{
precompute() ;
while (scanf("%d", &n) != EOF)
printf("%5d -> %d\n", n, fact_lnzd[n]) ;
return 0;
}
/* @END_OF_SOURCE_CODE */
Tuesday, March 1, 2011
0-1 Knapsack Code
#define MAX_ITEMS 20
#define CAPACITY 5000
int V[MAX_ITEMS+1][CAPACITY+1], K[MAX_ITEMS+1][CAPACITY+1] ;
/* Find a solution to maximizing VALUE while subjected to a maximum WEIGHT of W */
/* values[n+1] = {0, v1, v2, ...vn} ;
weights[n+1] = {0, w1, w2, ... wn} ;
n = total number of items
W = maximum capacity of the knapsack
*/
int knapsack01(int W, int n, int values[MAX_ITEMS+1], int weights[MAX_ITEMS+1])
{
int i, j, w, t, sol[MAX_ITEMS+1] ;
for (w=0; w<=W; w++)
V[0][w] = 0 ;
for (i=1; i<=n; i++) {
for (w=0; w<=W; w++) {
if (weights[i]<=w) {
t = values[i] + V[i-1][w-weights[i]] ;
if (V[i-1][w] > t) {
V[i][w] = V[i-1][w] ;
K[i][w] = 0 ;
}
else {
V[i][w] = t ;
K[i][w] = 1 ;
}
}
else {
V[i][w] = V[i-1][w] ;
K[i][w] = 0 ;
}
}
}
t = W ;
for (i=n, j=0; i>=1; i--) {
if (K[i][t]==1) {
sol[j++] = values[i] ;
t = t-weights[i] ;
}
}
for (--j; j>=0; j--)
printf("%d ", sol[j]) ;
return V[n][W] ;
}
Saturday, February 26, 2011
Sudoku
/* Su-Doku solver */
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX 9
struct _nextS
{
int res ;
int r ;
int c ;
} nextS[MAX][MAX] ;
int s[MAX][MAX], o[MAX][MAX] ;
int n=3, N=9, nosolution,
first_r, first_c ; /*first non-zero (row,col) with the least number of possible candidates */
void print(void)
{
int i, j ;
for (i=0; i<N; i++) {
printf("%d", s[i][0]) ;
for (j=1; j<N; j++)
printf(" %d", s[i][j]) ;
printf("\n") ;
}
printf("\n") ;
}
int canbefilled(int r, int c, int nextD)
{
int ans, si, sj, i, j ;
if (r>=0&&r<=2) si = 0 ;
else if (r>=3&&r<=5) si = 3 ;
else if (r>=6&&r<=8) si = 6 ;
if (c>=0&&c<=2) sj = 0 ;
else if (c>=3&&c<=5) sj = 3 ;
else if (c>=6&&c<=8) sj = 6 ;
ans = nextD ;
for (i=0; i<N; i++)
if (s[r][i] == nextD)
ans=0 ;
for (i=0; i<N; i++)
if (s[i][c] == nextD)
ans=0 ;
for (i=si; i<si+n; i++)
for (j=sj; j<sj+n; j++)
if (s[i][j] == nextD)
ans=0 ;
return ans ;
}
int compute_possible_candidates(void)
{
int i, j, nextD, k, min=10, d, ans=0 ;
for (i=0; i<N; i++) {
for (j=0; j<N; j++) {
if (o[i][j]==0) {
k = 0 ;
for (nextD=1; nextD<=9; nextD++) {
if (canbefilled(i, j, nextD)) {
d = nextD ;
k++ ;
}
}
if (k==1) {
o[i][j] = d ;
s[i][j] = d ;
ans = 1 ;
}
else if (k<min) {
min = k ;
first_r = i ;
first_c = j ;
}
}
}
}
return ans ;
}
/* Return the next square which is not originally filled */
int getnext(int *nr, int*nc)
{
int r, c ;
if (*nc==N) {
*nr = *nr+1 ;
*nc=0 ;
}
if (*nr==N)
*nr=0 ;
for (r=*nr; r<N; r++) {
for (c=*nc; c<N; c++)
if (o[r][c]==0)
{
*nr = r ;
*nc = c ;
return 1 ;
}
*nc = 0 ;
}
for (r=0; r<N; r++) {
for (c=0; c<N; c++)
if (o[r][c]==0)
{
*nr = r ;
*nc = c ;
return 1 ;
}
*nc = 0 ;
}
return 0 ;
}
int nf ;
int fillpos(int r, int c)
{
int i, j, ans, nextD, nr, nc ;
nf++ ;
do {
for (nextD=(s[r][c]?s[r][c]:1); nextD<=N; nextD++)
if (canbefilled(r, c, nextD)) {
s[r][c] = nextD ;
break ;
}
if (nextD>N) {
if (r==first_r && c==first_c) {
/* We tried everything, backtracking every path.
Now even first_r,first_c can't be filled */
nosolution = 1 ;
return 1 ;
}
s[r][c] = 0 ;
return 0 ;
}
if (nextS[r][c].res==0)
return 1 ;
else {
nr = nextS[r][c].r ;
nc = nextS[r][c].c ;
}
ans = fillpos(nr, nc) ;
}
while (!ans);
return 1 ;
}
int main()
{
int i, j, a, b, cases ;
freopen("sudoku.in", "r", stdin) ;
freopen("sudoku.out", "w", stdout) ;
scanf("%d", &cases) ;
while (cases--) {
for (i=0; i<N; i++)
for (j=0; j<N; j++) {
scanf("%d", &s[i][j]) ;
o[i][j] = s[i][j] ;
nextS[i][j].res = 0 ;
}
first_r = first_c = 0 ;
while (compute_possible_candidates()) ;
i = first_r ;
j = first_c ;
a = first_r ;
b = first_c + 1 ;
while (getnext(&a, &b)) {
if (a==first_r && b==first_c)
break ;
nextS[i][j].res = 1 ;
nextS[i][j].r = a ;
nextS[i][j].c = b ;
i = a ;
j = b ;
b = b+1 ;
}
a = first_r ;
b = first_c ;
nosolution = 0 ;
if (getnext(&a, &b))
fillpos(a, b) ;
if (nosolution)
printf("NO SOLUTION\n") ;
else print() ;
}
return 0;
}
/* sudoku.in */
1
0 6 0 1 0 4 0 5 0
0 0 8 3 0 5 6 0 0
2 0 0 0 0 0 0 0 1
8 0 0 4 0 7 0 0 6
0 0 6 0 0 0 3 0 0
7 0 0 9 0 1 0 0 4
5 0 0 0 0 0 0 0 2
0 0 7 2 0 6 9 0 0
0 4 0 5 0 8 0 7 0
Subscribe to:
Posts (Atom)