206 lines
4.3 KiB
C++
206 lines
4.3 KiB
C++
/* Check cf5-opt.vim defs.
|
|
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
|
|
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
|
|
VIM: let g:cppflags=g:Iboost.g:Itbb
|
|
VIM: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
|
|
VIM: let g:ldlibpath=g:Bboost.g:Btbb
|
|
VIM: let g:argv=""
|
|
*/
|
|
|
|
/*
|
|
Problem
|
|
|
|
Fegla and Omar like to play games every day. But now they are bored of all games, and they would like to play a new game. So they decided to invent their own game called "The Repeater".
|
|
|
|
They invented a 2 player game. Fegla writes down N strings. Omar's task is to make all the strings identical, if possible, using the minimum number of actions (possibly 0 actions) of the following two types:
|
|
|
|
Select any character in any of the strings and repeat it (add another instance of this character exactly after it). For example, in a single move Omar can change "abc" to "abbc" (by repeating the character 'b').
|
|
Select any two adjacent and identical characters in any of the strings, and delete one of them. For example, in a single move Omar can change "abbc" to "abc" (delete one of the 'b' characters), but can't convert it to "bbc".
|
|
The 2 actions are independent; it's not necessary that an action of the first type should be followed by an action of the second type (or vice versa).
|
|
|
|
Help Omar to win this game by writing a program to find if it is possible to make the given strings identical, and to find the minimum number of moves if it is possible.
|
|
|
|
Input
|
|
|
|
The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a line containing an integer N which is the number of strings. Followed by N lines, each line contains a non-empty string (each string will consist of lower case English characters only, from 'a' to 'z').
|
|
|
|
Output
|
|
|
|
For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is the minimum number of moves to make the strings identical. If there is no possible way to make all strings identical, print "Fegla Won" (quotes for clarity).
|
|
|
|
Limits
|
|
|
|
1 ? T ? 100.
|
|
1 ? length of each string ? 100.
|
|
|
|
Small dataset
|
|
|
|
N = 2.
|
|
|
|
Large dataset
|
|
|
|
2 ? N ? 100.
|
|
|
|
Sample
|
|
|
|
|
|
Input
|
|
|
|
Output
|
|
|
|
5
|
|
2
|
|
mmaw
|
|
maw
|
|
2
|
|
gcj
|
|
cj
|
|
3
|
|
aaabbb
|
|
ab
|
|
aabb
|
|
2
|
|
abc
|
|
abc
|
|
3
|
|
aabc
|
|
abbc
|
|
abcc
|
|
|
|
Case #1: 1
|
|
Case #2: Fegla Won
|
|
Case #3: 4
|
|
Case #4: 0
|
|
Case #5: 3
|
|
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <exception>
|
|
#include <stdexcept>
|
|
#include <map>
|
|
#include <set>
|
|
#include <list>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <functional>
|
|
#include <algorithm>
|
|
#include <utility>
|
|
#include <limits>
|
|
#include <math.h>
|
|
|
|
typedef long long i64;
|
|
typedef std::vector<i64> vec;
|
|
void check( bool b ) { if ( !b )
|
|
std::cerr << "error" << std::endl; }
|
|
#define FOR(i,l) for ( i64 i =0, ie = i64(l); i<ie; ++i )
|
|
/*
|
|
Read n values into v
|
|
*/
|
|
template <class V>
|
|
void readv( V& v, int n )
|
|
{
|
|
v.reserve(n);
|
|
for ( int i = 0; i < n; ++i )
|
|
{
|
|
typename V::value_type e;
|
|
std::cin >> e;
|
|
check( !std::cin.fail() );
|
|
v.push_back(e);
|
|
}
|
|
}
|
|
|
|
|
|
std::string solve_puzzle()
|
|
{
|
|
int n;
|
|
std::cin >> n;
|
|
|
|
std::vector<std::string> v;
|
|
readv( v, n);
|
|
|
|
std::vector<int> i(n,0);
|
|
std::vector<int> r(n,0);
|
|
|
|
int m = 0;
|
|
while ( true )
|
|
{
|
|
if ( i[0] < v[0].size() )
|
|
{
|
|
int c = v[0][i[0]];
|
|
FOR( j, n )
|
|
{
|
|
r[j] = 0;
|
|
while ( i[j]<v[j].size() && c == v[j][i[j]] )
|
|
{
|
|
i[j]++;
|
|
r[j]++;
|
|
}
|
|
if ( r[j] == 0 )
|
|
return "Fegla Won";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FOR( j, n )
|
|
{
|
|
if ( i[j]<v[j].size() )
|
|
return "Fegla Won";
|
|
}
|
|
break;
|
|
}
|
|
|
|
std::sort(r.begin(),r.end());
|
|
int am = 1000000;
|
|
for ( int a = r.front(); a <= r.back(); a++ )
|
|
{
|
|
int s = 0;
|
|
FOR(b,n)
|
|
{
|
|
s += abs(r[b]-a);
|
|
}
|
|
am = std::min(s,am);
|
|
}
|
|
m += am;
|
|
}
|
|
|
|
std::stringstream ss;
|
|
ss << m;
|
|
return ss.str();
|
|
}
|
|
|
|
#undef int
|
|
int main ( void )
|
|
{try{
|
|
srand((unsigned)time(NULL));
|
|
int puzzle_count;
|
|
|
|
std::cin >> puzzle_count;
|
|
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
|
|
for ( int i = 1; i <= puzzle_count; i++ )
|
|
{
|
|
std::cout << "Case #" << i << ": ";
|
|
auto r = solve_puzzle();
|
|
std::cout << r << std::endl;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
catch ( const std::exception& e )
|
|
{
|
|
std::cerr << std::endl
|
|
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
|
return 2;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
std::cerr << std::endl
|
|
<< "unknown exception." << std::endl;
|
|
return 1;
|
|
}}
|