『UVA 1610』聚会游戏

转载声明:http://blog.csdn.net/L123012013048/article/details/45049521

个人感想:这道题简直烧脑,主要是抓住的点好难,我只分析出2个点,然后就wa成狗,之后我只能借助一下参考文章,补上我缺失的点才能过,主要是没抓住重点.我想逐步的通过我的分析来重新理清思路,我觉得这种题不能像太复杂才行.

分析:
首先我们要决定中间串的位置,很明显,我们只要对所有字符串进行排序,通过比较中间得2个字符串即可,因为(T/2-1)小的串肯定也比要求的S串要小,同理则越大.那么我们分3段来处理2个字符串,假设c1串 < c2串(这是必然的,因为是通过排序出来的).
(1) len(c1)到了结尾,但len(c2)没到,那么ans最后一个字符直接等于c1[len1-1]就好了,因为c2多出来的部分肯定比c1大,例如 ABCD ABCEEEEEE 明显答案是ABCD;
(2)len(c1)没到结尾,但len(c2)到了结尾,我一开始是认为直接输出求出来的ans即可,可是我突然发现, 这种样例 AZZZDE ,B 如果直接输出答案B 或者A都是错的,所以我们得继续推,如果当前 c1【i】==Z,就直接ans+=c1[i],如果没达到结尾就直接 ans+=c1[i]+1, 所以答案应该为AZZZE(我一开始以为是字典序最小,没看清连len也得最小才行),还有一种情况就是AZZZD,B,答案并不是AZZZE,达到结尾直接ans+=c1[i]即可,答案AZZZD,才是最短而且字典序最小.
(3)这是len(c1)和len(c2) 都没到结尾的情况我们通过样例也可以返现, 如果c2[i]>c1[i]+1,那么最好的办法直接 ans+=(c1[i]+1)就好了,然后就可以输出结果了,但是如果 c2[i]==c1[i]+1呢?(这是我第2个点没注意的,我一开始以为直接就ans+=(c1[i])就好了,可是必然是错的),我们也得分情况讨论啊,例如ABCD,ABDE,这答案是ACD!!并不是ABCD,只要len(c2) 还没到结尾, 我可以直接获取 ans+(c2[i]),这才是答案.
总结:要耐心才可以,不要心燥,头疼就休息下,搞清楚情况就好了.

代码:

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */
//#define OUT
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define Clear(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
int T;
string name[1005];

int L[1005];
int num[1005];
int main()
{
#ifdef OUT
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    while(scanf("%d",&T),T)
    {

        for(int i=0;i<T;i++)
        {
            cin>>name[i];
            L[i]=name[i].length();
        }
        sort(name,name+T);

        string c1=name[T/2-1];
        string c2=name[T/2];
        string ans="";

        int len1=c1.length();
        int len2=c2.length();
        int len=max(len1,len2);
        for(int j=0;j<len;j++)
        {
            if(len1-1==j)
            {
                ans+=c1[j];
                break;
            }
            else if(len2<=j)
            {
               if(c1[j]=='Z'||j==len1-1)
               {
                   ans+=c1[j];
               }
               else
               {
                   ans+=(c1[j]+1);
                   break;
               }
            }
            else
            {

                if(c1[j]+1<c2[j]||c1[j]+1==c2[j]&&j!=len2-1)
                {
                    ans+=(c1[j]+1);
                    break;
                }
                else
                {

                   ans+=(c1[j]);
                }

            }
        }
        cout<<ans<<endl;


    }

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值