相信來看這篇文章的人有部分是不知道漏了哪些細節。。細節好多。。我也列不全,在這裏給出兩個易錯的樣例,各位在看代碼之前先看看樣例,說不定就恍然大悟了。
樣例1
2
ABCCC
AC
樣例2
2
ABZZZ
AC
下面來講講思路:對輸入的字符串進行排序後,我們的任務是找個一個最短字符串(在保證最短的前提下字典序儘量小)ans使得name[n/2-1]<=ans&&name[n/2]>ans;
字典序最小的(但是最長)肯定就是name[n/2-1]了。所以我們考慮如何修改name[n/2-1]去得到ans,所以我先將ans賦值爲name[n/2-1],我的思路是從name[n/2-1]與name[n/2]第一個不同字母的下標(記爲start)開始每次將ans[start]增加1(這樣得到的串一定是字典序最小的)同時將ans[start+1]改爲空字符'\0',如果這時ans滿足name[n/2-1]<=ans&&name[n/2]>ans那麼ans一定就是答案了,如果不符合,那麼我們將ans還原,遞增start重複上述步驟,直到start遞增到了[n/2-2]如果還不符合條件,那麼答案就是name[n/2-1]本身了(因爲如果start到了[n/2-1],修改ans[start]後的到的串的字典序一定大於name[n/2-1]了,所以name[n/2]顯然更優)。
AC代碼:
#include <string>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
string name[1005];
char ans[35];
int main(int argc, char const *argv[])
{
int n;
while(cin>>n&&n!=0)
{
memset(ans,0,sizeof(ans));
for(int i=0;i<n;i++)
cin>>name[i];
sort(name,name+n);
int start,l=name[n/2-1].size(),ok=0;
for(int i=0;i<l;i++)
{
ans[i]=name[n/2-1][i];
if(!ok&&ans[i]!=name[n/2][i])
{
start=i;
ok=1;
}
}
for(start;start<l-1;start++)
{
char t=ans[start+1];
ans[start+1]='\0';
ans[start]+=1;
string now(ans);
if(ans[start]<='Z'&&now<name[n/2]&&now>=name[n/2-1])
break;
else
{
ans[start+1]=t;
ans[start]--;
}
}
cout<<ans<<endl;
}
return 0;
}