繁体   English   中英

优化传递比较(A> B,B> C => A> C)

[英]Optimization of transitive comparison (A>B, B>C => A>C)

我已经在这个问题上停留了将近一个星期,而且我认为我需要一些帮助来解决它。 我以这种格式进行了一组比较:

5  
2  
1 2
2 3
3 4
5 4
6 5

第一行表示可以比较的5个元素(1-5)
第二行表示将有多少个比较语句
从第三行开始是比较语句。 第一个要素比第二个要素要好。 因此,在这种情况下1> 2,2> 3和3> 4等等。

我应该输出比每个元素更好和更坏的元素数量。 因此,没有数字比元素1更好,并且有3个数字比元素1(2,3,4)差。 我想你应该已经明白了。 输出应为:

1: better: 0 worse: 3
2: better: 1 worse: 2
3: better: 2 worse: 1
4: better: 5 worse: 0
5: better: 1 worse: 1
6: better: 0 worse: 2

到目前为止,这是我的实现

class Student{
public:
vector<int> better;
vector<int> worse;
};

void addComp(Student* student, int a, int b){

//push all worse elements into their better elements (there will be    duplicate)
student[a].worse.push_back(b);
vector<int>::iterator bIter = student[b].worse.begin();
vector<int>::iterator aIter = student[a].better.begin();

while (aIter != student[a].better.end())
{
    student[*aIter].worse.push_back(b);
    aIter++;
}

while (bIter != student[b].worse.end())
{
    student[a].worse.push_back(*bIter);

    aIter = student[a].better.begin();
    while (aIter != student[a].better.end())
    {
        student[*aIter].worse.push_back(*bIter);
        aIter++;
    }
    bIter++;
}

//push all better elements into their worse elements (there will be duplicate)
student[b].better.push_back(a);
bIter = student[b].worse.begin();
aIter = student[a].better.begin();

while (bIter != student[b].worse.end())
{
    student[*bIter].better.push_back(a);
    bIter++;
}

while (aIter != student[a].better.end())
{
    student[b].better.push_back(*aIter);

    bIter = student[b].worse.begin();
    while (bIter != student[b].worse.end())
    {
        student[*bIter].better.push_back(*aIter);
        bIter++;
    }
    aIter++;
 }
}

int main()
{
int studentCount, inputCount, testCase;
int a, b;
Student* student;

cin >> testCase;
while (testCase > 0)
{
    //The number of student that will be compared
    cin >> studentCount;

    student = new Student[studentCount + 1];

    //The number of comparison input
    cin >> inputCount;

    while (inputCount > 0)
    {
        cin >> a >> b;
        addComp(student, a, b);
        inputCount--;
    }

    //Start counting the number of better and worse student for each student
    for (int i = 1; i <= studentCount; i++)
    {
        //Remove duplicate from worse array
        sort(student[i].worse.begin(), student[i].worse.end());
        vector<int>::iterator last = std::unique(student[i].worse.begin(), student[i].worse.end());
        student[i].worse.erase(last, student[i].worse.end());

        //Remove duplicate from better array
        sort(student[i].better.begin(), student[i].better.end());
        vector<int>::iterator last2 = std::unique(student[i].better.begin(), student[i].better.end());
        student[i].better.erase(last2, student[i].better.end());

        cout << i " better: " << student[i].better.size() << " worse: " << student[i].worse.size() << endl;
    }
    delete [] student;
    testCase--;
 }
}

它工作得很好,但是对于此问题而言效率不够。 要比较的元素数最多可以为50个,比较语句的数量最多可以为10000s个比较语句。 而这仅是一个测试用例。 可以给出多个测试用例。 如果您能指出我一个更有效的算法或帮助优化我的代码,将不胜感激。

如何尝试消除addComp中的重复元素? 此外,您可以在addComp时对其进行排序。

我建议您使用set而不是vector,因为set可能是唯一的。 步骤1.将向量替换为set步骤2.将push_back替换为插入步骤3.删除排序部分

#include <set>
#include <algorithm>
#include <iostream>
using namespace std;

class Student{
public:
set<int> better;
set<int> worse;
};

void addComp(Student* student, int a, int b){

//push all worse elements into their better elements (there will be    duplicate)
student[a].worse.insert(b);
set<int>::iterator bIter = student[b].worse.begin();
set<int>::iterator aIter = student[a].better.begin();

while (aIter != student[a].better.end())
{
    student[*aIter].worse.insert(b);
    aIter++;
}

while (bIter != student[b].worse.end())
{
    student[a].worse.insert(*bIter);

    aIter = student[a].better.begin();
    while (aIter != student[a].better.end())
    {
        student[*aIter].worse.insert(*bIter);
        aIter++;
    }
    bIter++;
}

//push all better elements into their worse elements (there will be duplicate)
student[b].better.insert(a);
bIter = student[b].worse.begin();
aIter = student[a].better.begin();

while (bIter != student[b].worse.end())
{
    student[*bIter].better.insert(a);
    bIter++;
}

while (aIter != student[a].better.end())
{
    student[b].better.insert(*aIter);

    bIter = student[b].worse.begin();
    while (bIter != student[b].worse.end())
    {
        student[*bIter].better.insert(*aIter);
        bIter++;
    }
    aIter++;
 }
}

int main()
{
int studentCount, inputCount, testCase;
int a, b;
Student* student;

cin >> testCase;
while (testCase > 0)
{
    //The number of student that will be compared
    cin >> studentCount;

    student = new Student[studentCount + 1];

    //The number of comparison input
    cin >> inputCount;

    while (inputCount > 0)
    {
        cin >> a >> b;
        addComp(student, a, b);
        inputCount--;
    }

    //Start counting the number of better and worse student for each student
    for (int i = 1; i <= studentCount; i++)
    {
        cout << i << " better: " << student[i].better.size() << " worse: " << student[i].worse.size() << endl;
    }
    delete [] student;
    testCase--;
 }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM