UVA1610 聚会游戏 Party Games 题解
个人认为一个比较好理解的解法.
思路:
先对所有字符串进行排序.
只需考虑中间那两个串.先预先判断一下两个串的相同部分,让下标k预先到两个串不同的部分.
设第n/2个串为a串,它下一个串为b串
当遇到不同的字符直接跳出循环,如果k到了a串的最后一个字符都还没发现不同的,那么a串本身就满足条件(此处没考虑k是否超出b串的长度,不过最后提交上去也ac了,代码如下
int i=n/2;
string ans;
int k=0;
for(k=0;s[i][k];k++)
{
if(s[i][k]==s[i+1][k]) ans+=s[i][k];
else break;
}
判断完相等部分后,我们需要继续判断后面的部分
假设当判断到了第k个字符时
一、如果第k个字符是a串的最后一个字符,则a串就是答案串
二、如果第k个字符不是a串最后一个字符
①第k个字符小于Z时,如果它+1后与前面的ans串组合起来要小于b串,那么第k个字符+1 加到ans中就是答案.否则(大于等于b串)我们还是用a串的第k个字符加到ans串中
②第k个字符等于Z时,没有比Z更大的字符,也就无法根据①的方法来创造出来答案串,所以把第k个字符就直接加到ans串中,接着判断后面的。
那么最上面那部分预先判断相等部分的字符串的代码就没有留着的必要了,因为这也包含在上述情况之中.
完整代码献上
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1010;
int main()
{
// freopen("uva1610.txt","r",stdin);
while(1)
{
int n;
string s[N];
scanf("%d",&n);
if(n==0) break;
for(int i=1;i<=n;i++)
{
cin>>s[i];
}
sort(s+1,s+n+1);
int i=n/2;
string ans;
int k=0;
while(k<(int)s[i].size())
{
if(k==(int)s[i].size()-1)//一、如果第k个字符是a串的最后一个字符,则a串就是答案串
{
ans=s[i];
break;
}
//二、如果第k个字符不是a串最后一个字符
if(s[i][k]<'Z')//①第k个字符小于Z时
{
string t=ans;
t+=(s[i][k]+1);
if(t<s[i+1])
{
ans=t;
break;
}
else
{
ans+=s[i][k];
k++;
continue;
}
}
else //②第k个字符等于Z时
{
ans+=s[i][k];
k++;
continue;
}
}
cout<<ans<<endl;
}
return 0;
}
代码可能有一些冗余,不过我觉得这样比较方便理解.
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通