洛谷: P1781 宇宙总统
https://www.luogu.com.cn/problem/P1781
题目:
地球历公元 6036 年,全宇宙准备竞选一个最贤能的人当总统,共有 n 个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统。
输入:
第一行为一个整数 n,代表竞选总统的人数。
接下来有n 行,分别为第一个候选人到第 n 个候选人的票数。
输出:
共两行,第一行是一个整数 m,为当上总统的人的号数。
第二行是当上总统的人的选票。
样例:
输入:
5
98765
12365
87954
1022356
985678
输出:
4
1022356
分析:
问题在票数的大小位数会达到100,因此只能通过string
输入,比较大小方法这里提供了字典序的比较。
字典序比较的标准就是对于两个string类型的字符串,比较两个字符串第一个不相容的元素的字典顺序,这也要求了在本题中字典序比较起作用的前提是二者位数相等,因此在排序的过程中修改一下判断的条件就可以,或者重载比较运算符也可以,这里我采取的修改if条件。
要么字符串的长度小,要么字符串的长度相同并且字典序小,才能等价为票数小。
代码如下:(可以用stl里面的sort,也可以自己写)
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std;
class pre
{
public:
int len;
int posi;
string s;
};
pre p[100];
int ca(pre *num, int left, int right)
{
pre key = num[left];
while(left < right)
{
while(left < right && ( (num[right].s <= key.s && num[right].len == key.len) || num[right].len < key.len) )
{
right--;
}
if(left < right)
{
num[left] = num[right];
}
while(left < right && ( (num[left].s >= key.s && num[left].len == key.len) || num[left].len > key.len) )
{
left++;
}
if(left < right)
{
num[right] = num[left];
}
}
num[left] = key;
return left;
}
void quick_sort(pre *num, int left, int right)
{
if(left < right)
{
int index = ca(num, left, right);
quick_sort(num, left, index - 1);
quick_sort(num, index + 1, right);
}
}
/*bool cmp(pre a,pre b)
{
if(a.len>b.len) return 1; //前一个比后一个位数多,不交换
if(a.len==b.len&&a.s>b.s) return 1; //位数相同,但前一个按字典序排列比后一个大,也不交换。
return 0; //剩下情况均要交换。
}*/
int main()
{
int n;
int ans = 0;
cin>>n;
for(int i = 0;i < n;i++)
{
cin>>p[i].s;
p[i].len = p[i].s.size();
p[i].posi = i + 1;
}
int max = 0;
//sort(p,p + n,cmp);
quick_sort(p, 0, n - 1);
cout<<p[0].posi<<endl;
cout<<p[0].s<<endl;
return 0;
}