Link:
Http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_ problem&problem=1073
Type: Greedy + backtracking
Original title:
The Problem
Your friend, a biochemistry major, tripped while carrying a tray of computer files through the lab. All of the files fell to the ground and broke. Your friend picked up all the file fragments and called your to ask for help putting them back together again.
Fortunately, all of the files on the tray were identical, all of them broke to exactly two, and all of the fragments E fragments were found. Unfortunately, the files didn ' t all broke in the same place, and the fragments were completely-mixed up by their fall to T He floor.
You ' ve translated the original binary fragments into strings of ASCII 1 ' s and 0 ' s, and you ' re planning to write a To determine the bit pattern the contained.
Input
The input begins with a single positive integer in a line by itself indicating the number of cases following, each of them as described below. This are followed by a blank line, and there are also a blank line between two consecutive.
Input would consist of a sequence of ' ' File fragments ', one per line, terminated by the end-of-file marker. Each fragment consists of a string of ASCII 1 ' s and 0 ' s.
Output
For each test case, the output must follow the description below. The outputs of two consecutive cases is separated by a blank line.
The Output is a single line of ASCII 1 ' s and 0 's giving the bit pattern of the original files. If There are 2N fragments in the input, it should is possible to concatenate this fragments together in pairs to make N C Opies of the output string. If there is no unique solution, any of the possible solutions may be output.
Your Friend is certain this there were no more than 144 files on the tray, and which the files were all less than 256 bytes in size.
Sample Input
1
011
0111
01110
0111
10111
Sample Output
01110111
The main effect of the topic:
Your friend was carrying a plate with n copies of the same document, but accidentally dropped the plate on the floor, and every file was broken into 2 pieces. Now the string consisting of 0,1 represents the original file, and then enter all the "fragments" to find the original file based on the fragments.
Analysis and Summary:
More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/
The first time I saw this, I thought of it as backtracking, but the direct backtracking must be timed out, with greedy thoughts and some cuts.
First, the length of the original string is required, which is equal to the shortest string length and the longest string length.
Then, sort all the strings by length from small to large.
Then there is the process of backtracking search:
When backtracking is done, the first is to enumerate all the possible original strings and search for a match for the current original string.
When matching, because the string has been sorted based on length, assuming the total is N, then one of the "fragments" used to assemble must be in the 0~N/2 and the other must be in the (n/2+1) ~n. According to this conclusion, when enumerating two fragments, the first layer for loop search range is from 1~ (N/2), and the second layer for loop is (n-1) ~ (n/2+1). In the second loop, the n-1 is inverted from the top, and once the two lengths are less than the original length, you can exit directly.
This method has a final run time of 0.008s.
Price:
* * * Uva:10132-file fragmentation * time:0.008s * author:d_double * * * * * * * * * * #include <cstdio> #include &L t;cstring> #include <iostream> #include <algorithm> #include <map> #define MAXN-using name
Space Std;
Map<string, bool>mp;
Char str[maxn][260], ans[260];
int NFile, Len;
BOOL VIS[MAXN], flag;
int cmp (const void *a, const void *b) {int L1=strlen ((char*) a), L2=strlen ((char*) b);
if (L1!=L2) return l1-l2;
Return strcmp ((char*) A, (char*) b);
} inline void input () {nfile=0;
int minlen=10000, maxlen=-10000;
while (gets (Str[nfile])) {if (!str[nfile][0)) break;
int L=strlen (str[nfile]);
if (L<minlen) minlen=l;
if (L>maxlen) maxlen=l;
++nfile; } Len=maxlen+minlen;
Find the length of the original string, equal to the minimum fragment length and the maximum fragment} void search (int cnt, char *file) {if (flag) return;
if (CNT==NFILE/2) {strcpy (ans, file); Flag=true;
Return
for (int i=0; i<nfile/2; ++i) if (!vis[i]) {vis[i] = true;
if (cnt==0) {//When CNT equals 0 o'clock, enumerate all possible "original strings" for search for (int j=nfile-1; j>=nfile/2;--j) if (!vis[j)) {
int L=strlen (Str[i]) +strlen (str[j)); if (L<len) return;
The reduction, when the length is less than the original length, exits because the back length will be smaller if (L>len) continue;
Char temp1[300];
strcpy (Temp1, str[i]);
strcat (Temp1, str[j]);
if (!mp[temp1]) {//Map to check if this string has been searched, this is very important!!
Mp[temp1]=true;
VIS[J] = true;
Search (cnt+1, TEMP1);
} Char temp2[300];
strcpy (Temp2, str[j]);
strcat (Temp2, str[i]);
if (strcmp (Temp1, TEMP2) ==0) continue;
if (!MP[TEMP2]) {//Map to check if this string has been searched, this is very important!! Mp[teMp2]=true;
Vis[j]=true;
Search (cnt+1, TEMP2);
} Vis[j] = false; } else{for (int j=nfile-1; j>=nfile/2;--j) if (!vis[j]) {int l=str
Len (Str[i]) +strlen (Str[j]);
if (L<len) return;
if (L>len) continue;
Char temp1[300];
strcpy (Temp1, str[i]);
strcat (Temp1, str[j]);
if (strcmp (temp1, file) ==0) {Vis[j] = true;
Search (cnt+1, TEMP1);
} Char temp2[300];
strcpy (Temp2, str[j]);
strcat (Temp2, str[i]);
if (strcmp (Temp1, Temp2)!=0) {Vis[j] = true;
Search (cnt+1, TEMP2);
} Vis[j] = false;
} } Vis[i] = false;
int main () {int T;
scanf ("%d%*c", &t); Gets (str[0]);
Eliminates empty row while (t--) {input ();
Qsort (str, nFile, sizeof (str[0)), CMP);
memset (Vis, 0, sizeof (VIS));
Mp.clear (); Char t[10]= "ABC";
Pass a parameter to go in Flag=false;
if (nfile>2) search (0, T);
else{strcpy (ans, str[0]); strcat (ans, str[1]);
Puts (ans);
if (T) printf ("\ n"); }
}
Author: csdn Blog shuangde800