UVA1610 Party Games

相信來看這篇文章的人有部分是不知道漏了哪些細節。。細節好多。。我也列不全,在這裏給出兩個易錯的樣例,各位在看代碼之前先看看樣例,說不定就恍然大悟了。

樣例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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章