Judge:https://vjudge.net/problem/UVA-1610
题意:输入一些字符串,找一个长度最短的字符串(不一定是输入的字符串),使得输入的字符串中有一半小于等于该字符串,另一半大于该字符串。若有多解,输出字典序最小的解。
可以使用二分法。
要注意优先输出长度最短的字符串,另外要保证strA[i - 1] + 1是一个字符。
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int g_iStrTot;
string g_arrStr[1010];
bool GetResult(string strA, string strB, int iLimit, string & strResult)
{
string strTmp = "";
for (int i = 1; i <= iLimit; i++)
{
if (strTmp + strA[i - 1] >= strA && strTmp + strA[i - 1] < strB)
{
strTmp += strA[i - 1];
strResult = strTmp;
return true;
}
else if (isalpha(strA[i - 1] + 1) && strTmp + (char)(strA[i - 1] + 1) >= strA && strTmp + (char)(strA[i - 1] + 1) < strB)
{
strTmp += (char)(strA[i - 1] + 1);
strResult = strTmp;
return true;
}
strTmp += strA[i - 1];
}
return false;
}
int main()
{
while (cin >> g_iStrTot, g_iStrTot)
{
for (int i = 1; i <= g_iStrTot; i++)
cin >> g_arrStr[i];
sort(g_arrStr + 1, g_arrStr + 1 + g_iStrTot);
string strA = g_arrStr[g_iStrTot / 2], strB = g_arrStr[g_iStrTot / 2 + 1];
int iLeft = 0, iRight = strA.length() + strB.length(), iMid;
string strResult;
while (iLeft + 1 < iRight)
{
iMid = iLeft + (iRight - iLeft) / 2;
if (GetResult(strA, strB, iMid, strResult))
iRight = iMid;
else
iLeft = iMid;
}
cout << strResult << endl;
}
return 0;
}