Algorithm 如何解决SPOJ上的问题?

Algorithm 如何解决SPOJ上的问题?,algorithm,greedy,Algorithm,Greedy,我正在努力解决这个SPOJ问题 我的方法 for all elements in the preferred_position array if(position>0&&position<=n) if(position is unoccupied) allocate position for user else reach the first free position in the array for all elements wh

我正在努力解决这个SPOJ问题

我的方法

for all elements in the preferred_position array
 if(position>0&&position<=n)
    if(position is unoccupied)
       allocate position for user
 else
   reach the first free position in the array

for all elements whose preferred position is already filled
    search both directions left,right to find nearest free_position
首选位置数组中所有元素的


如果(位置>0&&position这是我接受的解决方案

我发送了几次,直到意识到数字可能非常大,所以我将所有内容都改为long-long

只需对数字进行排序,然后找出其位置之间的差异

我是如何找到这个解决方案的:

1) 你应该把所有的队伍放在从0到n-1的位置

2) 让我们把尽可能多的团队安排在他们喜欢的位置

3) 其余未被安排的队伍的首选位置与被安排的相同 团队或首选职位较大,则n-1(或n-if 从1开始枚举)

4) 因为我们记得我们需要把所有的位置从0降到n-1, 因此,很明显,如果我们对未定位的团队进行排序,我们可以将其最小化 答案

为什么我跳过第二步(你们可以试着证明它),让我们看看示例测试:

#包括
#包括
#包括
使用名称空间std;
int main(){
ios::与stdio同步(false);
长t;
cin>>t;
载体a;
for(长i=0;i>n;
a、 清除();
对于(长j=0;j>s;
长p;
cin>>p;
p--;
a、 推回(p);
}
排序(a.begin(),a.end());
长ans=0;
用于(长i=0;i
阅读您的代码非常痛苦。您的解决方案不是100%正确,因为:

  • 可能会有非常大的数字大于10^10,你做错了什么-将这个数字减少1,直到你达到n,你的生命太短暂了,等你的解决方案找到这样大的数字进行测试的结果…(如果你希望a[i]小于或等于n,为什么不写一个[i]=n

  • 我在同一个测试用例上运行了您的代码两次,但都是在第二次 运行I更改测试中给定数字的顺序,您的解决方案将显示 不同的答案:

    我删除了读取字符串以便于调试。因此,我提供了不带团队名称的测试

    首次运行测试:

    一,

    十,

    2345678976

    您的解决方案显示结果是6(出了什么问题 (答复)

    第二次运行:让我们更改交换最后两个数字并获得

    2 3 4 5 6 7 8 9 6 7

    您的解决方案显示答案是8(幸运的是它是 (正确答案)

  • 假设有两个未定位的数字a[6]=6a[9]=9, 及 有两个自由位置1和8

    您的解决方案将采取6正确的两步并将6置于8位置,然后采取9并置于1位置

    如果您从编号的起始位置到编号的起始位置绘制线 目的地您将看到从9到1的线路完全覆盖6到8的线路看起来不是最佳线路

    因此,您应该尽量避免这种重叠

    现在从6到1和从9到8画线,没有 重叠,现在它是最佳的

    So to avoid overlapping   you can for example to sort rest of your numbers.
    

  • 谢谢!我不明白这是如何导致最佳解决方案的,因为位置\u preferred和位置\u allocated的变化可能会导致后续元素的变化。我首先定位了首选位置在范围内且位置为空的元素。后来我遍历了左侧和右侧,以获得元素的最近位置谁的首选位置已被占用。我错在哪里?这里有一个指向代码@user i know测试用例的链接,您的解决方案将落在该测试用例上。我将尝试形式化和解释。非常感谢@d40a,对于错误和难以理解的代码,我深表歉意
        #include <iostream>
        #include <vector>
        #include <algorithm>
    
        using namespace std;
        int main() {
            ios::sync_with_stdio(false);
            long long t;
            cin >> t;
            vector <long long> a;
            for (long long i = 0; i < t; i++) {
               long long n;
               cin >> n;
                a.clear();
                for (long long j = 0; j < n; j++) {
                    string s;
                    cin >> s;
                    long long p ;
                    cin >> p;
                    p--;
                    a.push_back(p);
                }
                sort(a.begin(), a.end());
                long long ans = 0;
                for (long long i = 0; i < a.size(); i++) {
    
                    ans += abs(a[i] - i);
                }
                cout << ans << '\n';
           }
        }
    
    while(t2>n)
        {
            t2--;
            cnt1++;
        }
    
    So to avoid overlapping   you can for example to sort rest of your numbers.