uva 1610 Party Games

题目大意:就是给定n个不同的名字,n为偶数,现在问使得其中一半小于或者某个字符串,而另一半大于这个字符串的长度最小的(若有多解,则字典序最小)的串是什么。

解题:题目意思很好懂,做题步骤是先排序,然后查找满足题意的串

这里主要是要注意一点。。。一定要先考虑长度,再考虑字典序。

同时注意到  最终的串的前缀是mid-1和mid+1串的共同前缀。不同和陷阱也就是在后面的字符该如何确定。。。

设第一个字符不同的位置时pos,且mid+1的pos位置的值一定是大于mid-1相同位置的。

注意两个原则:串可以等于mid-1的串;二最终的串可以取mid+1上面的字符,且如果能取得话那么最终的长度不会超过pos+1+1.

具体的看代码,很容易理解。

//
//  main.cpp
//  uva 1610 - Party Games
//
//  Created by XD on 15/8/15.
//  Copyright (c) 2015年 XD. All rights reserved.
//

#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespace std ;
string name[1010]  ;
int getGreaterPos(int l , int r )
{
    int l1 = (int )name[l].length() ;
    int l2 = (int)name[r].length() ;
    int i = 0 , j=0 ;
    while (i < l1 || j < l2 ) {
        if (i == l1) {
            return l1 ;
        }
        else if (name[l][i] < name[r][j])
        {
            return j ;
        }
        i++;j++ ;
    }
    return 0  ;
    
}


int main() {
    int n ;
    while (scanf("%d" ,&n),n!=0) {
        for (int i = 0; i < n ; i++) {
            cin>>name[i]  ;
        }
        sort(name, name + n ) ;
        int  l = n /2 - 1 , r = n /2 ;
        int len1 = (int )name[l].length() ; int len2 = (int)name[r].length() ;
        int pos = getGreaterPos(l,r) ;
        if (pos ==len1) {
            cout<<name[l] ;
        }
        else{
            for(int i = 0 ; i < pos ; i++)
            {
                cout<<(char)name[l][i] ;
            }
            if (pos == len1-1) {
                cout<<(char)(name[l][len1-1]) ;
                cout<<endl;
                continue ;
            }
            if (name[r][pos] - name[l][pos] > 1) {
                cout<<(char)(name[l][pos] + 1)  ;
            }
            else{
                char result1[31] ;char result2[31] ;
                int  r1=0,r2=0 ;int tpos = pos ;
                //求result1
                result1[r1++] = name[l][tpos] ;
                tpos++ ;
                while (tpos < len1) {
                    if (name[l][tpos] == 'Z') {
                        result1[r1++] = 'Z' ;
                        tpos++ ;
                        continue ;
                    }
                    if(tpos == len1-1)    {
                        result1[r1++] = name[l][tpos] ;
                        break ;
                    }
                    result1[r1++] = name[l][tpos] +1;
                    break ;
                }
                //求result2
                int flag = 1  ;
                tpos =pos ;
                result2[r2++] = name[r][tpos++] ;
//                if(len2 - tpos >= 1 )
//                {
////                    if (name[r][tpos]>'A') {
////                        result2[r2++] = 'A' ;
////                    }
////                    else{
////                        flag = 0  ;
////                    }
//                    ;
//                }
//                else
                    if (len2 - tpos == 0)
                {
                    flag = 0 ;
                }
//                else{
//                    result2[r2++] = 'A' ;
//                }
                
                //判断result1和result2
                if (flag==0) {
                    for (int i = 0; i < r1; i++) {
                        printf("%c" , result1[i]) ;
                    }
                    
                }
                else{
                    if (r1 > r2) {
                        for (int i = 0;i < r2 ; i++) {
                            printf("%c" ,result2[i]) ;
                        }
                    }
                    else{
                        for (int i = 0; i < r1; i++   ) {
                            printf("%c" , result1[i]) ;
                        }
                    }
                }
                
            }
        }
        cout<<endl ;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值