首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

C++长int
EN

Stack Overflow用户
提问于 2014-10-18 09:02:07
回答 2查看 5.5K关注 0票数 0

因此,我有以下问题:

下个月将在这个城市举行一次大型会议。朋友通常会一起来登记,所以他们也会坐在一起,和他们已经认识的人聊天。为了使事情变得更有情趣,会议组织者想出了一个系统来“洗牌”与会者的顺序,从而让他们认识新的人。 该系统的工作原理如下:第一个到达会议登记的人获得由组织者随机选择的一个号码为a1的门票。以下每个到达的人都会得到一张新的票,号码是ai = (ai -1×31334) mod 31337,并在队列中找到相应的位置,就在最后一个小于或等于ai的人后面。这意味着排队的票号应该始终保持顺序,如果已经有许多人拥有相同的号码,那么最后一次到达的应该是这一组中的最后一个。 您的任务是编写一个计算机程序,以帮助服务人员找到他们在队列中的正确位置。 例如,给定初始票号a1 = 7546,请在到达的第6个人的队列中找到位置。这里的输入是7546,6。 讨论:第一个到达的人得到了a1 = 7546的票,并站在排队的前面。第二个人得到a2 = (7546×31334) mod 31337 = 8699,因此站在排队的第二位。到达的第三个人得到号码为a3 = (8699×31334) mod 31337 = 5240的票,因此,可以跳出队列,站在1位置,将排队中的其他人移到后面。也就是说,队列现在看起来是: 1: 5240 (3),2: 7546 (1),3: 8699 (2),入场券号码按递增顺序排列,亲生票数是与会者到达会议的原始顺序。 继续这个序列,第四、第五和第六参与者将得到票证编号a4= 15617、a5 = 15823和a6 = 15205;这样队列就会看起来像: 1: 5240 (3),2: 7546 (1),3: 8699 (2),4: 15205 (6),5: 15617 (4),6: 15823 (5),即第6人到达队列中的第4位。 答:4

以及以下c++代码:

代码语言:javascript
运行
复制
#include <iostream>
using namespace std;
int main ()
{
    int n, i, poz, ok;
    long long int a, v[100], aux;
    cout << "v[1]= "; cin >> v[1];
    cout << "n= "; cin >> n;
    for (i=2; i<=n; i++)
        v[i]=(v[i-1]*31334)%31337;
    a=v[n]; 
    do
    {
        ok=0;
        for (i=1; i<n; i++)
            if (v[i]>v[i+1])
            {
                aux=v[i];
                v[i]=v[i+1];
                v[i+1]=aux;
                ok=1;
            }
    }while (ok==1);
    for (i=1; i<=n; i++)
        if (v[i]==a)
            poz=i;
    cout << poz;
    return 0;
}

它为小数字显示正确的东西,但当我输入较大的数字时,问题就出现了,因为它只是简单地断裂。例如,它显示4表示7253,10显示1表示24284,10,但当我输入12879 505时,显示中断。有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2014-10-18 09:17:42

即使不检查您的代码,我也可以说整数溢出不应该是一个问题,即使对于signed int

31337² = 982,007,569,它是111010100010000011111100010001,一个30位数。

因此,在任何时候,这里的计算都不应超过最大INT,即(2^31)-1 = 2,147,483,647。就像一件琐事一样,long long int会支持(2^63)-1 = 9,223,372,036,854,775,807的数字。

现在需要做的是调试代码..。

根据您的错误--我认为问题在于您定义了大小为100的arrav v,并试图找到第505元素--这本质上是非法的内存访问,因此不可预测。您正在对自己的代码执行缓冲区溢出:)

除此之外,我建议您花费一些时间来组织代码-- #define或为常量添加const值(数组大小、31337、31334等)。记住,C++中的数组以v[0]开头,而不是以v[1]开头--无论文本描述是什么。这是一个错误。将forif语句封装为块{ },即使在它们后面只有一个表达式--或者将来添加代码时,您会忘记它们,并进行“有趣”的调试。

作为一项一般性建议--省去一些麻烦,养成使用尤达案例的习惯:1 == ok而不是ok == 1,因为一次错误将它转换为ok = 1会导致非常严重的错误。

票数 1
EN

Stack Overflow用户

发布于 2014-10-18 09:32:47

您应该考虑使用向量并将值推回。

但是你的数组超出了界限。您做了一个大小为100的数组,并在上次测试运行时尝试使用505个空格。

因此,要么使用向量并push_back您的值,要么增加数组的大小。为了便于使用,我建议使用向量。

下面是一些我拼凑在一起解决您的问题的东西,使用容器和STL函数为您完成大部分工作。希望这能帮到你。=)

代码语言:javascript
运行
复制
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

using LONG64 = long long;

const int MULTIPLIER = 31334;
const int MOD = 31337;

int main()
{
    vector<LONG64> ticket;

    cout << "v[1]= ";
    LONG64 seed;
    cin >> seed;
    ticket.emplace_back(seed);

    cout << "n= ";
    int queue_spot;
    cin >> queue_spot;

    for (auto i = 1; i <= queue_spot; ++i) {
        auto seed_number = (ticket[i - 1] * MULTIPLIER) % MOD;
        //cout << "\nseed_number " << seed_number;
        ticket.emplace_back(seed_number);
    }

    LONG64 person_ticket_number = ticket[queue_spot - 1];

    cout << "\nPerson's ticket number " << person_ticket_number;

    sort(ticket.begin(), ticket.end());

    auto spot = find(ticket.begin(), ticket.end(), person_ticket_number);

    cout << "\nPerson is in spot " << (spot - ticket.begin()) + 1 << endl;

    system("PAUSE");
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26438000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档