|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
calcolo possibili combinazioni matrice numerica col limite somma
Salve a tutti,
sto cercando di creare un algoritmo che mi consenta di fare quanto segue: Ho una matrice ad esempio 4x4 con 16 valori numeri generati random compresi da 1 a 9. Voglio conteggiare tutte le possibili combinazioni di quei numeri che mi dia come somma ad esempio il numero 10. matrice: 6 5 3 8 6 9 1 2 3 1 2 1 7 5 6 1 generata random. in questo caso ad esempio posso ottenere 10 in vari modi...e il conteggio deve muoversi logicamente anche in diagonale, in avanti e indietro, senza ripetizioni. Ho provato a vedere ogni posto della matrice come un indice e a sommarlo al successivo finchè non ottengo 10, ma non so proprio come muovermi in tutte le direzioni possibili. Ho letto che forse serve il backtracking ma non sono riuscito ad usarlo. Sapreste aiutarmi? Grazie mille ![]()
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
Quote:
Senza voler scomodare altri linguaggi tipo il C ho usato VBA Codice:
Dim yy As Integer Sub calcola() yy = 1 For y = 1 To 4 For x = 1 To 4 Call pippo(y, x) Next x, y End Sub Sub pippo(x, y) camp = Cells(y, x) For colonna = 1 To 4 For riga = 1 To 4 If (riga <> y Or colonna <> x) And Cells(y, x) + Cells(riga, colonna) = 10 Then tmp$ = Cells(y, x) tmp$ = tmp$ + "," tmp$ = tmp$ + Str(Cells(riga, colonna)) Cells(yy, 7) = tmp$ yy = yy + 1 tmp$ = "" Cells(riga, colonna) = 0 End If Next riga, colonna End Sub basta copiare e incollare i tuoi valori in un foglio di Excel da A1,D4 |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
cosi somma solo i numeri vicini 2 a 2. io ho bisogno che continua a sommare in tutte le direzioni. capito che intendo magari parti dal centro va a destra da li può continuare tornando indietro avanti o in diagonale!
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
![]() |
![]() |
![]() |
#4 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
6 5 3 8 6 9 1 2 3 7 2 1 1 5 6 1 Potrei considerare valida la sequenza di numeri 8 1 1 della seconda diagonale(anche se in mezzo ai due 1 c'è il 7)? |
|
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
Quote:
non ne riesco a venire a capo...
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
|
![]() |
![]() |
![]() |
#6 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Eventualmente in C ti va bene la soluzione?
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
si credo di si, eventualmente sarebbe solo un problema di sintassi da cambiare. ora stiamo usando VBA per praticità.
Grazie mille, confido in te! ![]()
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
![]() |
![]() |
![]() |
#8 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
![]() ![]() Come torno a casa me lo studio un po'. ![]() P.S.: È un problema simile a quello che abbiamo trattato in uno dei nostri contest: il 3 o il 4 mi pare. EDIT: Si, è il 3: http://www.hwupgrade.it/forum/showthread.php?t=1787500 ![]() Ultima modifica di Vincenzo1968 : 07-02-2013 alle 17:32. |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
Quote:
Prende un numero, partendo dal primo e lo somma con tutti gli altri della matrice e se soddisfa i requisiti lo azzera. (x1,y1)+(x2,y2) se = 10(x2,y2)=0 e continua così sino a x4,y4 passa poi a x2,y2 e lo somma con tutti gli altri uno ad uno e se soddisfa i requisiti lo azzera. Se invece intendevi che 10 può essere formato da più numeri allora non si era capito affatto cosa volevi ottenere oppure, che si può partire da una posizione arbitraria allora è un altro tipo di problema etc.... p.s. metti sempre degli esempi di output in modo che si ben chiaro cosa vuoi ottenere. Ultima modifica di misterx : 08-02-2013 alle 05:59. |
|
![]() |
![]() |
![]() |
#10 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Prima mi sono sbagliato. Il problema è simile a quello che abbiamo affrontato nel contest 5:
http://www.hwupgrade.it/forum/showthread.php?t=1799059 ![]() |
![]() |
![]() |
![]() |
#11 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Ecco questo è il codice che avevo utilizzato per il contest 5:
Codice:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <time.h> #define BUFFER_SIZE 4096 typedef enum tagStati { S_ERROR = -1, S0, S1, S2 } Stati; typedef struct tagArray { int **m; int side; } Array; typedef struct tagResult { int row1; int col1; int row2; int col2; int sum; } Result; int GetArraySize(const char *szFileName) { int array_size; FILE *fp; char buffer[BUFFER_SIZE + 1]; int numread; int k; char c; fp = fopen(szFileName, "rb"); if ( fp == NULL ) { printf("Errore nell'apertura del file %s\n", szFileName); return S_ERROR; } numread = fread(buffer, 1, BUFFER_SIZE, fp); if (numread == 0) { fclose(fp); printf("Errore 4 nella lettura del file %s\n", szFileName); return S_ERROR; } *(buffer + numread + 1) = '\0'; k = 0; c = *(buffer + k); array_size = 0; while ( c != '\n' ) { if ( c >= '0' && c <= '9' ) { array_size = array_size * 10 + c - '0'; } c = *(buffer + k++); } fclose(fp); return array_size; } Stati DFA(const char *szFileName, Array *pArray) { Stati stato = S0; FILE *fp; unsigned char buffer[BUFFER_SIZE + 1]; int numblocks; int numread; char c; int k, x; int riga, colonna; int num; int segno; pArray->side = GetArraySize(szFileName); if ( pArray->side <= 0 ) { printf("Errore nella lettura del file.\n"); return S_ERROR; } pArray->m = (int**)calloc(pArray->side + 1, sizeof(int*)); if ( pArray->m != NULL ) { for ( x = 0; x < pArray->side + 1; x++ ) { pArray->m[x] = (int*)calloc(pArray->side + 1, sizeof(int)); if ( pArray->m[x] == NULL ) { printf("Memoria insufficiente.\n"); return S_ERROR; } } } else { printf("Memoria insufficiente.\n"); return S_ERROR; } fp = fopen(szFileName, "rb"); if ( fp == NULL ) { printf("Errore nell'apertura del file %s\n", szFileName); return S_ERROR; } if ( fseek(fp, 0, SEEK_END) ) return 0; numblocks = ftell(fp)/BUFFER_SIZE; if ( numblocks == 0 ) { numblocks = 1; } else { if ( ftell(fp) % BUFFER_SIZE != 0 ) numblocks++; } fseek(fp, 0, SEEK_SET); numread = fread(buffer, 1, BUFFER_SIZE, fp); if (numread == 0) { fclose(fp); printf("Errore 1 nella lettura del file %s\n", szFileName); return S_ERROR; } k = 0; c = *(buffer + k++); while ( c != '\n' ) { if (c == '\0') { printf("Errore 2 nella lettura del file.\n"); fclose(fp); return S_ERROR; } c = *(buffer + k++); } riga = colonna = 0; num = 0; x = 0; while ( x < numblocks ) { c = *(buffer + k++); switch ( stato ) { case S0: segno = 1; if ( c >= '0' && c <= '9' ) { num = c - '0'; stato = S1; } else if ( c == '-' ) { num = 0; stato = S2; } else if ( c == '\r' ) { } else if ( c == '\n' ) { colonna = 0; riga++; if (riga >= pArray->side) return stato; } else { printf("Automa: Stato S0 errore sul carattere -> '%c' k -> %d\n", c, k); return S_ERROR; } break; case S1: if ( c >= '0' && c <= '9' ) { num = num * 10 + c - '0'; } else if ( c == ' ' || c == '\r' || c == '\n' ) { pArray->m[riga + 1][colonna + 1] = num * segno; num = 0; colonna++; stato = S0; } else { printf("Automa: Stato S1 errore sul carattere -> '%c'\n", c); return S_ERROR; } break; case S2: if ( c >= '0' && c <= '9' ) { num = c - '0'; segno = -1; stato = S1; } else { printf("Automa: Stato S2 errore sul carattere -> '%c'\n", c); return S_ERROR; } break; } if ( k >= BUFFER_SIZE ) { numread = fread(buffer, 1, BUFFER_SIZE, fp); if (numread == 0) { fclose(fp); printf("Errore 3 nella lettura del file %s\n", szFileName); return S_ERROR; } k = 0; x++; } } fclose(fp); return stato; } int FindKadaneSquareSubmatrix(Array *pArray, Result *pRes) { int Somma; int i, t, m, n, z, x, y, s; int riga, colonna, dim; int **column; column = (int**)calloc(pArray->side + 1, sizeof(int*)); if ( column != NULL ) { for ( x = 0; x < pArray->side + 1; x++ ) { column[x] = (int*)calloc(pArray->side + 1, sizeof(int)); if ( column[x] == NULL ) { printf("Memoria insufficiente.\n"); return S_ERROR; } } } else { printf("Memoria insufficiente.\n"); return S_ERROR; } m = pArray->side; n = pArray->side; // somma dell'intero array Somma = 0; for( y = 1; y <= pArray->side; y++ ) { for( x = 1; x <= pArray->side; x++ ) { Somma += pArray->m[y][x]; } } pRes->sum = Somma; pRes->row1 = 1; pRes->col1 = 1; pRes->row2 = m; pRes->col2 = n; // singoli elememti for( y = 1; y <= pArray->side; y++ ) { for( x = 1; x < pArray->side; x++ ) { s = pArray->m[y][x]; if ( s > Somma ) { Somma = s; pRes->row1 = y; pRes->col1 = x; pRes->row2 = y; pRes->col2 = x; } } } for ( z = 1; z <= m; z++ ) { for ( i = 1; i <= n; i++ ) { column[z][i] = column[z - 1][i] + pArray->m[z][i]; } } s = 0; for ( dim = 2; dim <= pArray->side; dim++ ) { for ( riga = 1; riga <= pArray->side - dim + 1; riga++ ) { s = 0; for ( x = 1; x <= dim; x++ ) { s += column[riga + dim - 1][x] - column[riga-1][x]; } if ( s > Somma ) { Somma = s; pRes->sum = s; pRes->row1 = riga; pRes->col1 = 1; pRes->row2 = dim + 1; pRes->col2 = dim + 1; } for ( colonna = x; colonna <= pArray->side; colonna++ ) { t = column[riga + dim - 1][colonna - dim] - column[riga - 1][colonna - dim]; s += column[riga + dim - 1][colonna] - column[riga-1][colonna]; s -= t; if ( s > Somma ) { Somma = s; pRes->sum = s; pRes->row1 = riga; pRes->col1 = colonna - dim + 1; pRes->row2 = riga + dim - 1; pRes->col2 = colonna; } } } } return 0; } int main() { clock_t c_start, c_end; Array a; Result res; Stati stato; char *szFileName = "C:\\Scaricamenti\\Temp\\Gugo\\Contest5\\matrix1.txt"; c_start = clock(); stato = DFA(szFileName, &a); if ( stato == S_ERROR ) { printf("L'automa ha restituito un errore.\n"); return; } c_end = clock(); printf("\nTempo impiegato per la lettura del file -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); c_start = clock(); FindKadaneSquareSubmatrix(&a, &res); c_end = clock(); printf("\nRiga1 -> %d\nColonna1 -> %d\n\nRiga2 -> %d\nColonna2 -> %d\n\nSomma -> %d\n\n", res.row1, res.col1, res.row2, res.col2, res.sum); printf("Tempo impiegato per la ricerca -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); return 0; } ![]() |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
mmmm difficilotto da adattare x me. non è che mi potresti fare un esempio per quello che serve a me? grazie mille
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
Quote:
esatto intendo che può essere formato da + combinazioni di numeri de qualsiasi posizione e verso...purchè siano adiacenti.
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
|
![]() |
![]() |
![]() |
#14 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Potremmo farlo semplicemente con backtracking, ma sarebbe estremamente inefficiente. Ultima modifica di Vincenzo1968 : 08-02-2013 alle 12:41. |
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
|
![]() |
![]() |
![]() |
#16 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Così va bene?
![]() Trova le sequenze di numeri con somma = 10. Considerando solo le righe. Se va bene lo amplio per la ricerca sulle colonne e sulle diagonali. |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
Va benissimo. Anche io avevo fatto qualcosa del genere ma mi manca proprio la parte per farlo cercare anche in diagonale e colonna. Il punto è che se avanza per riga poi può cambiarepercorso x colonna o x ddiagonale. Da ogni punto della matrice deve poter continuare in ogni direzione. Immaginatevi ruzzle il gioco che va tantodi moda adesso . Uno può comporre la parola in qualsiasi modo purché adiacenti. Dovrei fare la stessa cosa ma con i numeri.
Grazie mille
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
![]() |
![]() |
![]() |
#18 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Così?
![]() Mancano ancora le diagonali. |
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 704
|
Esatto... Praticament gli stai ffacendo fare tre controlli diversi.. Uno per riga uno per colonna e uno per le diagonali? E se si muove su più direzioni? Se prima scende per colonna poi va per diagonale e poi per riga? Capito che intendo? Ad esempio 4 4 2 Nell angolo in basso a destra è una soluzione valida
__________________
Aerocool Coolview with Gatewatch(modded) - Asus P5B Deluxe - Core 2 duo E6600 @ 3700(463*8) cooled by Zalman 9500led - Corsair 2*1GB XMS2 DDR2 PC6400 1:1 4-4-4-12 - XFX 7600GT XXX with vf700al-cu - LcPower Scorpio 480W - HD 250GB 7200.9 Seagate Barracuda - Nec DVD-RW+- |
![]() |
![]() |
![]() |
#20 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:16.