20.选举

目录

题目

思路

具体步骤

C++完整代码(含详细注释)


题目

在遥远的相簿国有两个种族,分别是冬马族和雪菜族,每个人都属于这两个种族之一。如今,又到了选举元首的时候了,所有 n 个人排成一排等待投票。

    相簿国的选举制度比较奇特,并不是看谁的票数多,而是使用一票否决制度,并且所有人都可以投一张票或者不投票。如果排在前面的人把排在后面的人一票否决了,那么后面的人不能参与竞选,也不能投出他的那一票了。而如果排在后面的人把排在前面的人一票否决了,那么排在前面的人不能参与竞选,但是已经投出的那一票仍然有效。如果一轮投完仍然有不只一个竞选者,那么这些留下的人再投一轮,还没有停止就再投一轮……直到剩下一人为止,但投票的先后顺序不变。

为了保证每轮投票中都有更多人可以投票,规定竞选者优先给在他投票时已经投过票的异族人,每轮投票结束时重置竞选人的投票状态

    所有人都希望自己族的人能当选元首(而不是希望自己当元首),并且会为此采取最优策略。现在给出排队中每个人的种族,请问最后是哪个种族的人会当选元首?

输入

输入第一行一个数 n ,表示相簿国里的人数。

第二行一个长度为 n 的字符串 s ,从前到后依次表示排队投票的人所属的种族。D 表示冬马族,而 X 表示雪菜族。

输出

输出一个字符 D 或 X ,表示是哪一族的人当选。

注意

数据保证1<=n <=200000。

测试用例

用例1.

输入:

5↵

DDXXX↵

输出:

D↵

用例2.

输入:

6↵

DDXXXX↵

输出:

X↵


思路

我们首先需要明确每一个族人有两种权利:投票权竞选权

因此,

我们可以用D和X分别记录有投票权的族人;

使用栈(stack)来存放仍有竞选权的族人。

值得注意的是,

前面的一个人能够让后面的异族人同时丧失投票权和竞选权,

因为“如果排在前面的人把排在后面的人一票否决了,那么后面的人不能参与竞选,也不能投出他的那一票了”;

而要让前面的一个人丧失投票权和竞选权则需要后面的两个异族人,

因为“如果排在后面的人把排在前面的人一票否决了,那么排在前面的人不能参与竞选,但是已经投出的那一票仍然有效

简单来说,是因为需要一个异族人去花掉前面的人的投票权,另一个异族人使用竞选权让前面的人丧失竞选权。


具体步骤

代码首先输入选票的数量和选票字符串。然后遍历字符串,检查当前选票是“D”还是“X”。根据当前选票和栈中现有的竞选人,确定具有当前选票的候选人是否有权竞选或需要被淘汰。

如果当前选票是“D”且没有具有投票权的“X”候选人,则将“D”候选人加入栈中,并增加“D”票数。如果栈中有“X”候选人,则“D”候选人可以淘汰栈中的所有“X”候选人,并将自己加入栈中。

如果当前选票是“X”且没有具有投票权的“D”候选人,则将“X”候选人加入栈中,并增加“X”票数。如果栈中有“D”候选人,则“X”候选人可以淘汰栈中的所有“D”候选人,并将自己加入栈中。

在遍历完所有选票后,代码计算栈中剩余的候选人数量。栈中候选人数量较多的种族被宣布为获胜者。如果剩余候选人数量对于两个种族来说是相同的,则根据栈中最后一个候选人确定获胜者。


C++完整代码(含详细注释)

#include 
#include 
using namespace std;

int main() {
    int n;
    string s;
    stack st;//栈用于存放还有竞选权的人
    int D = 0, X = 0;//记录两个种族的投票权
    cin >> n;
    cin >> s;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == 'D') {//遍历到D时
            if (X == 0) {//如果X的投票权为0,则说明D有竞选权和投票权
                if (st.empty()) {//栈为空
                    st.push('D');
                    D++;
                }
                else {//栈不为空
                    if (st.top() == 'D') {//栈顶为D
                        st.push('D');
                        D++;
                    }
                    else {//栈顶为X,则需要D使用投票权将前面的X淘汰,但自己仍有竞选权
                        st.pop();//将前面的X淘汰
                        int num = 1;//记录X的淘汰人数和D的竞选人数
                        while (i X1) cout << 'D' << endl;
    else if (X1 > D1) cout << 'X' << endl;
    else cout << last << endl;//竞选者人数相同,则在前面(即栈顶)的种族会赢,因为前面的可以让后面的失去投票权

    return 0;
}


你可能感兴趣的:(程序设计方法与实践,算法,数据结构,c++)