解题报告 之 UVA1610 Party Games

解题报告 之 UVA1610 Party Games


Description

You've been invited to a party. The host wants to divide the guests into 2 teams for party games, with
exactly the same number of guests on each team. She wants to be able to tell which guest is on which
team as she greets them when they arrive. She'd like to do so as easily as possible, without having to
take the time to look up each guest's name on a list.
Being a good computer scientist, you have an idea: give her a single string, and all she has to do is
compare the guest's name alphabetically to that string. To make this even easier, you would like the
string to be as short as possible.
Given the unique names of n party guests (n is even), nd the shortest possible string S such that
exactly half the names are less than or equal to S, and exactly half are greater than S. If there are
multiple strings of the same shortest possible length, choose the alphabetically smallest string from
among them.

Input

There may be multiple test cases in the input.
Each test case will begin with an even integer n (2 n 1; 000) on its own line.
On the next n lines will be names, one per line. Each name will be a single word consisting only of
capital letters and will be no longer than 30 letters.
The input will end with a `0' on its own line.

Output

For each case, print a single line containing the shortest possible string (with ties broken in favor of the
alphabetically smallest) that your host could use to separate her guests. The strings should be printed
in all capital letters.

Sample Input

4
FRED
SAM
JOE
MARGARET
2
FRED
FREDDIE
2
JOSEPHINE
JERRY
2
LARHONDA
LARSEN
0

Sample Output

K
FRED
JF
LARI

 ---------------------------------------------------------------------

今天这道题简直卡爽了。感觉第一周完不成计划要请吃饭了。。。囧。。。这个题思路很简单,但是细节很多。建议先把每种情况想完,再证明正确了之后再写代码。


题目大意:给n个字符串(n为偶数),求一个字符串S使得n个字符串中恰有一半小于等于S,另一半大于S,要求使得S的长度尽量小,且在长度相等时输出字典序最小解。


简要讲一下思路吧 。首先最简单的一层就是,将n个字符串排序,则问题转换成了求S,使得S大于等于第n/2大的字符串L,小于n/2+1大的字符串R。接下来我们讨论几种不同的情况:我们分别扫描L和R对应位置i上的字符,如果发现L[i]+1<R[i],即L第i个字符至少比R第i个字符隔了两个字符,那么此时就直接将第i位+1输出即可;如果L[i]+1==R[i],那么我们不敢轻易断定可以直接+1输出,而是要看R[i]是不是R的最后一位,如果是最后一位就不能这么干,比如ABBA ABC,这时如果扫到第三位'B'+1=='C',如果S直接输出ABC就错了,因为题目要求了另一半要大于S。然后做的时候可能会出现L长度>R长度而出现R越界的情况,比如AAAB AAB。此时i=3时根据之前说的因为R中的B是最后一位所以不能输出AAB,那么继续比较的话R就没有货了。此时我采用的方法是给B加一位'Z'+1即可。

最后很自然会发现,当L都已经没有货了的时候直接输出L就是了。


我发现我的思路和主流解题报告的思路似乎不一样。。。感觉我是个杀马特。。囧


常见的比较坑的情况有:

2

AAAZAAA

AAB

2

ABAB

BABA


然后上代码吧。


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
using namespace std;

string s[1010];

int fun(string l, string r)
{
	int i = 0;
	while (l.length()>i&&l.length()>i)
	{
		if (l.length() <= i) return i+1;
		if (r.length() <= i) r += ('Z' + 1);
		if (l[i] + 1 < r[i] || (l[i] + 1 == r[i] && r.length()>i+1))
			return i+1;
		i++;
	}
	return i+1;

}

int main()
{
	int n;
	while (cin >> n&&n)
	{
		for (int i = 1; i <= n; i++)
			cin >> s[i];
		sort(s, s + n+1);
		int l = n / 2, r = n / 2 + 1;
		int key = fun(s[l], s[r]);

		string ans="";
		if (key >= s[l].length())
			ans = s[l];
		else
		{
			ans = string(s[l].begin(), s[l].begin() + key);
			ans[key - 1]++;
		}
		cout << ans << endl;
	}
	return 0;
}


虽然得知我做错地方了。但是我怀着接下来一个星期每天三道的决心还是整起走。可怜

,.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值