微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

一种算法 超出时间限制

如何解决一种算法 超出时间限制

主题链接https://codeforces.com/contest/109/problem/D

对于这个问题,我在 test41 上超出了时间限制

我猜是用的数据结构不合适,但是想了很久,不知道从哪里采用好的数据结构,请大家给点建议。

算法思路:

这种方法有点类似于选择排序。先找一个幸运数字,然后和第一个数字交换位置,然后从第二个开始,找到最小的数字,再和这个幸运数字对调,这样从第二个数字开始的最小的数字放在第一位位置,幸运数字现在在另一个位置,并记录其位置。 然后将幸运数字与第二个数字交换,然后重复上述过程。需要特别注意的是,我们排序后需要记录我们选择的幸运数字的位置,因为位置前后的过程略有不同,需要进行比较(这在代码注释中有说明)。


using namespace std;
typedef long long ll;

// Judge whether it is a lucky number. if it is a lucky number,return true,otherwise,return false.
bool judge(string x);


bool static cmp(vector<ll> a,vector<ll> b) { return a[0] < b[0]; }

int main()
{
    int n;
    cin >> n;
    vector<ll> nums;
    ll smLuckyNum = INT64_MAX;
    for(int i = 0; i < n; i++)
    {
        ll x;
        cin >> x;
        nums.push_back(x);
        if(judge(to_string(x)) && smLuckyNum > x) smLuckyNum = x;  // Find the smallest lucky number
    }

    vector<vector<ll> > b;  // b[i][0] stores nums[i],b[i][1] stores i index

    int pos,origIndex;
    bool sorted = true;
    
    // b[i][0] stores nums[i] and b[i][1] stores i index
    for(int i = 0; i < n; i++)
    {
        vector<ll> tmp;
        tmp.push_back(nums[i]);
        tmp.push_back(i);
        b.push_back(tmp);
    }

    sort(b.begin(),b.end(),cmp);  // sort by b[i][0]

    // If the original array is ordered,sorted == true,sorted == false
    for(int i = 0; i < n; i++)
        if(b[i][1] != i) sorted = false;

    // If the original array is not ordered and there is no lucky number in it,no way to sort,return -1
    if(!sorted && smLuckyNum == INT64_MAX) { cout << -1 << endl; return 0; }
    // If the original array is ordered,no sorting required
    if(sorted) { cout << 0 << endl; return 0; }

    // Find the position of the smallest lucky number,origIndex is the index of the smLuckyNum before sorting,pos is the index of the smLuckyNum after sorting
    for(int i = 0; i < n; i++)
    {
        if(smLuckyNum == b[i][0])
        {
            origIndex = b[i][1];
            pos = i;
            break;
        }
    }

    vector<string> ans;
    // Traverse the nums array from 0 to n - 2,if  i is equal to pos(the index of smLuckyNum after sorting),continue.
    // We can swap the element at position i and the element at position origIndex,and record the position of LuckyNum after the swap in origIndex,// then find the smallest element from i+1 to n-1 and record the index in MINID,notice if i > pos,and  nums[MINID] > nums[pos] (because there may be a large number placed at pos),the element at pos is smallest number
    // if MINID < n,swap(nums[i](it is a lucky number),nums[MINID])
    for(int i = 0; i < n - 1; i++)
    {
        if(i == pos) continue;

        string res = "";
        if(i != origIndex)
        {
            res += (to_string(i + 1) + " " + to_string(origIndex + 1)); // According to the requirement of the question,the index starts from 1,the result needs to plus one.
            swap(nums[i],nums[origIndex]);
            origIndex = i;
            ans.push_back(res);
        }

        ll MINID = i + 1;
        for(int j = i + 1; j < n; j++)
            if(nums[MINID] > nums[j]) MINID = j;

        if(i > pos && nums[MINID] > nums[pos]) MINID = pos;
        if(MINID < n)
        {
            res = "";
            res += (to_string(i + 1) + " " + to_string(MINID + 1));
            swap(nums[i],nums[MINID]);
            origIndex = MINID;
            ans.push_back(res);
        }
    }

    // Finally we need to compare nums[n - 1] with nums[pos] when pos != n - 1
    if(pos + 1 != n && nums[pos] > nums[n - 1])
        ans.push_back(to_string(pos + 1) + " " + to_string(n));

    cout << ans.size() << endl;
    
    for(int i = 0; i < ans.size(); i++)
        cout << ans[i] << endl;
    
    return 0;
}


bool judge(string x)
{
    for(int i = 0; i < x.size(); i++)
        if(x[i] != '4' && x[i] != '7') return false;
    return true;
}

解决方法

用于查找 MINID 的嵌套循环使运行时在 n 中二次:

for(int j = i + 1; j < n; j++)
    if(nums[MINID] > nums[j]) MINID = j;

当 n = 100,000 时,这将花费很长时间。您需要找到一种更好的方法来计算 MINID

提示:您在开始时准备 b[],然后永远不要使用它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。