Farmer John has gone out for a walk down the road and thinks he may now be lost!
Along the road there are NN farms (1≤N≤1001≤N≤100) in a row. Farms unfortunately do not have house numbers, making it hard for Farmer John to figure out his location along the road. However, each farm does have a colorful mailbox along the side of the road, so Farmer John hopes that if he looks at the colors of the mailboxes nearest to him, he can uniquely determine where he is.
Each mailbox color is specified by a letter in the range A..Z, so the sequence of NN mailboxes down the road can be represented by a string of length NN containing letters in the range A..Z. Some mailboxes may have the same colors as other mailboxes. Farmer John wants to know what is the smallest value of KK such that if he looks at any sequence of KK consecutive mailboxes, he can uniquely determine the location of that sequence along the road.
For example, suppose the sequence of mailboxes along the road is 'ABCDABC'. Farmer John cannot set K=3K=3, since if he sees 'ABC', there are two possible locations along the road where this consecutive set of colors might be. The smallest value of KK that works is K=4K=4, since if he looks at any consecutive set of 4 mailboxes, this sequence of colors uniquely determines his position along the road.
The first line of input contains NN, and the second line contains a string of NN characters, each in the range A..Z.
Print a line containing a single integer, specifying the smallest value of KK that solves Farmer John's problem.
7 ABCDABC
4
Problem credits: Brian Dean
[/hide]
(Analysis by Nick Wu)
Because NN is at most 100100, one approach that comes to mind is checking if K=1K=1 is valid. If so, then the answer is 11 and we can stop. Otherwise, we check if K=2K=2 is valid. We'll keep on increasing KK until it reaches NN, as K=NK=N is guaranteed to be valid.
How do we check if a given value of KK is valid? We can loop over all pairs of substrings of length KK and compare them for equality. My code following this approach is as follows:
#include <iostream> using namespace std; int main() { freopen("whereami.in", "r", stdin); freopen("whereami.out", "w", stdout); int n; string s; cin >> n >> s; for(int guess = 1; guess <= n; guess++) { bool good = true; for(int i = 0; i + guess <= n; i++) { for(int j = 0; j < i; j++) { if(s.substr(i, guess) == s.substr(j, guess)) { good = false; } } } if(good) { cout << guess << "\n"; break; } } }
It is possible to do faster by using a data structure known as a set. Sets cannot store duplicate elements but are able to quickly identify if a given element is already part of the set. Therefore, to check if a given value of KK is valid using a set, we can check if a substring is present in the set before inserting it. If some substring is already present, then the given value of KK is invalid.
Here is Brian Dean's solution using a set.
#include <iostream> #include <fstream> #include <string> #include <set> using namespace std; int N; string S; bool dups(int len) { set<string> X; for (int i=0; i<=N-len; i++) { if (X.count(S.substr(i,len)) > 0) return true; X.insert(S.substr(i,len)); } return false; } int main(void) { ifstream fin ("whereami.in"); ofstream fout ("whereami.out"); fin >> N >> S; int ans = 1; while (dups(ans)) ans++; fout << ans << "\n"; return 0; }
[/hide]
© 2024. All Rights Reserved. 沪ICP备2023009024号-1