"Russian doll problem" Program (capable of handling sparse matrix)

Source: Internet
Author: User

// ================================================ ==========================================

// File name: matrix. h
// Desp: Russian doll prize, Matrix
// Author: 905a Group

// Last update:

// ================================================ ==========================================

# Include <list>
# Include <algorithm>
# Include <iomanip>
# Include <iostream>
Using namespace STD;

Struct einmat
{
Int X;
Int y;
Int operator = (const einmat & right) const
{
Return x = right. X? (Y = right. Y? 1:0): 0;
}
};

Class Matrix
{
Public:
Matrix (INT countrow, int countcol)
{
Nrows = countrow;
Ncols = countcol;
Int size = countrow * countcol * sizeof (INT );
Elements = (int *) malloc (size );
Padval = (int *) malloc (size );
Memset (padval,-2, size );
};
~ Matrix ()
{
Free (elements );
Free (padval );
};

Int seekmaxgain (einmat cure, list <einmat> & vpath );
Void outputpath (list <einmat> & vpath );
 
Inline Int & element (int x)
{
Return * (elements + x );
}
 
Inline Int & element (einmat E)
{
Return * (elements + ncols * E. x + E. y );
}
 
PRIVATE:
Int nrows;
Int ncols;
Int * elements; // used to record Matrix Elements
Int * padval; // used to record the fill value when the matrix element is 0
Int validemat (einmat cure); // determines whether the current element is valid, that is, whether it exceeds the boundary of the matrix.
Int seekmat (einmat cure, list <einmat> & vpath );

// Determine whether the next element to be traversed is already in the vpath
Int inpath (const int ncure, const einmat nexte, list <einmat> & vpath );

// Determine the next traversal direction starting from the current element. elements that can be traversed are recorded using the linked list vnextes.
Int findnexte (einmat cure, list <einmat> & vnextes );

// Insert elements that can be traversed into the linked list vnextes according to the size of the matrix element value
Void insertlist (INT ncure, einmat nexte, list <einmat> & vnextes );

Inline Int & npadval (einmat E)
{
Return * (padval + ncols * E. x + E. y );
}
};

 

// The above is the definition of the class, followed by the implementation of the class

# Include "matrix. H"

Int matrix: seekmaxgain (einmat cure, list <einmat> & vpath)
{
Int sum;
Int & ncure = element (CURE );
If (ncure = 0)
{
Ncure =-1; // if the first element is 0, the value is-1.
Sum = seekmat (cure, vpath );
Ncure = 0;
Return sum + 1;
}
Else
Return seekmat (cure, vpath );
}

/******************* Input: ***********************
Cure: Current element
Sum: Sum of the current path
In the recursive process, vpath is used to record the path traversal.
Prerequisite: use this function when the first element is not 0.
**************************************** ***********/

Int matrix: seekmat (einmat cure, list <einmat> & vpath)
{
List <einmat> vnextes;
Int ncure = element (CURE );
 
// If the next element cannot be found, the current element is the end point, put the current element in the linked list, and then return
If (! Findnexte (cure, vnextes ))
{
Vpath. push_back (CURE );
Return ncure;
}
 
Int tempsum, maxsum =-1; // use tempsum to record the current sum, use maxsum to record the largest sum, and initialize it to-1, indicating that no search is started
Bool bzero;
// Search from the next element. If the element already exists in the previous search, it is skipped;
// Until the next element search of the current element is completed (up to 3)
For (list <einmat >:: const_iterator iter = vnextes. Begin ();
ITER! = Vnextes. End (); ITER ++)
{// Element 0 to be processed
List <einmat> temppath; // record the current path. Use vpath to record the maximum path.
Einmat nexte = * ITER;
Int & nnexte = element (nexte );
If (! Inpath (ncure, nexte, vpath) // check whether the start point of the search is already in the maximum path. Here there may be some optimizations.
{
Bzero = nnexte = 0;
If (bzero)
{
Nnexte = ncure; // for processing 0, assign the next element to the current element
Npadval (nexte) = ncure; // fill Value
}
Tempsum = seekmat (nexte, temppath );
If (bzero) tempsum-= ncure; // for processing 0, and subtracting the value of the current element is the real value.
If (tempsum> maxsum) // if the current sum is greater than the maximum value, the current sum is assigned to the maximum value, and the current path is assigned to the maximum path.
{
Maxsum = tempsum;
Vpath = temppath;
}
If (bzero) nnexte = 0; // for processing 0, restore to 0
}
}
 
Vpath. push_back (CURE );
Return ncure + maxsum;
}

Void matrix: outputpath (list <einmat> & vpath)
{
For (list <einmat >:: reverse_iterator iter = vpath. rbegin ();
ITER! = Vpath. rend ();
++ ITER)
{
Cout <SETW (4) <element (* ITER );
}
}

// Determine whether the current element cure is in the path vpath
Int matrix: inpath (const int ncure, const einmat nexte, list <einmat> & vpath)
{
For (list <einmat >:: const_iterator iter = vpath. Begin ();
ITER! = Vpath. End (); ITER ++)
{
If (* iter = nexte)
{
If (element (nexte) // if the next element is not 0, it indicates that it is in the path
Return 1;
Else if (ncure = npadval (* ITER ))
// If the value of the next element is 0, you also need to determine whether the current value and the fill value are consistent. If they are consistent, they are in the path.
Return 1;
}
}
Return 0;
}

// Determine the elements to be searched based on the current element. A maximum of three directions are allowed;
// The elements in the returned vnextes are arranged in the ascending order of the matrix.
Int matrix: findnexte (einmat cure, list <einmat> & vnextes)
{
Int ncure = element (CURE); // Current Value
Einmat nexte;
 
// Upload
Nexte. x = cure. X-1;
Nexte. Y = cure. Y;
Insertlist (ncure, nexte, vnextes );
// Right
Nexte. x = cure. X;
Nexte. Y = cure. Y + 1;
Insertlist (ncure, nexte, vnextes );
// Lower
Nexte. x = cure. x + 1;
Nexte. Y = cure. Y;
Insertlist (ncure, nexte, vnextes );
// Left
Nexte. x = cure. X;
Nexte. Y = cure. Y-1;
Insertlist (ncure, nexte, vnextes );
Return vnextes. Size ();
}

Void matrix: insertlist (INT ncure, einmat nexte, list <einmat> & vnextes)
{
Int nnexte = element (nexte );
If (! Validemat (nexte) & (nnexte = 0 | nnexte> ncure ))
{
For (list <einmat >:: iterator iter = vnextes. Begin ();
ITER! = Vnextes. End (); ITER ++)
If (element (* ITER)> = nnexte) break;
Vnextes. insert (ITER, nexte );
}
 
}

// Determine whether the current element is out of the Boundary. If the boundary is exceeded, 1 is returned. If the element is normal, 0 is returned.
Int matrix: validemat (einmat cure)
{
If (cure. x <0 | cure. x> = nrows | cure. Y <0 | cure. Y> = ncols)
{
Return 1;
}
Return 0;
}

 

// The next step is the main program

 

// ================================================ ==========================================
// Desp: Russian doll prize, main program

// Author: 905a Group
// Last update:
// ================================================ ==========================================

# Include "matrix. H"
# Include <ctime>
# Include <iostream>
# Include <fstream>
# Include <string>
Using namespace STD;

 

Int main (INT argc, char * argv [])
{
// Read the file
// DWORD ncouts;
Ifstream infile;
String file;

Cout <"Enter the matrix file you want to traverse:/N ";
Cin> file;
While (1)
{
Infile. Open (file. c_str ());
If (infile)
{
Cout <"Open File" <file <"success! "<Endl;
Int temp, nrows, ncols;

Infile> nrows; // number of rows
Infile> ncols; // Number of Columns
Matrix mattest (nrows, ncols );
Int I = 0;

Cout <"the original matrix is as follows:/N ";
While (infile> temp)
{
Mattest. element (I ++) = temp;
Cout <SETW (4) <mattest. element (I-1 );
If (I % ncols = 0)
{
Cout <Endl;
}
}
If (I! = Nrows * ncols)
{
Cout <"The entered data is incorrect. Check the entered data. /N ";
Return-1;
}
Cout <Endl;

Einmat Pos = {0, 0 };
Int sum;
List <einmat> vpath;

Clock_t start, finish;
Double duration;
Start = clock ();

Sum = mattest. seekmaxgain (Pos, vpath );

Finish = clock ();
Duration = (double) (finish-Start)/clocks_per_sec;

Cout <"/n the running time of this program is" <duration <"seconds! "<Endl;
Cout <"The traversal result is as follows:/N ";
Mattest. outputpath (vpath );
Cout <"/n maximum sum:" <sum <Endl;

Infile. Close ();
Infile. Clear ();
}
Else
{
Cout <"Open File" <file <"failed! "<Endl;
Return-1;
}
Cout <"exit. Enter Q and press enter to end. Otherwise, enter the file to be opened:/N ";
Cin> file;
If (file. c_str () [0] = 'q') break;
}

Return 0;
}

 

/* The following is the test data: 1.txt

 

4
1 16 15 0
2 17 0 24
3 0 18 25
4 19 0 20

Test data: 2.txt

15 15
1 56 55 54 53 52 51 50 49 48 47 46 45 44 43
2 57 104 103 102 101 100 99 98 97 96 95 94 93 42
3 58 105 144 143 142 141 140 139 138 137 136 135 92 41
4 59 106 145 176 175 174 173 172 171 170 169 134 91 40
5 60 107 146 177 200 199 198 197 196 195 168 133 90 39
6 61 108 147 178 201 216 215 214 213 194 167 132 89 38
7 62 109 148 179 202 217 224 223 212 193 166 131 88 37
8 63 110 149 180 203 218 225 222 211 192 165 130 87 36
9 64 111 150 181 204 219 220 221 210 191 164 129 86 35
10 65 112 151 182 205 206 207 208 209 190 163 128 85 34
11 66 113 152 183 184 185 186 187 188 189 162 127 84 33
12 67 114 153 154 155 156 157 158 159 160 161 126 83 32
13 68 115 116 117 118 119 120 121 122 123 124 125 82 31
14 69 70 71 72 73 74 75 76 77 78 79 80 81 30
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

Test data: 3.txt

6 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 1

 

*/

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.