三星研究院上机题(Order of task)

Thereare V tasks to do. Some task(s) can begin only after a particular task ends,which we will call precedence relation. A graph indicating precedence relationof tasks is given. In this graph, each task is denoted as vertex, and the precedencerelation as directed edge. Note there is no cycle with this graph (cycle refers to a path that starts from one vertex and returns to the same vertex). The graph below is one example of such graph



In this graph, task 1 can start after task 4 ends and task 6can when task 5 and task 7 end; there is no cycle with this graph.

Manager Kim is going to finish a set of tasks having precedencerelation by taking care of one task at a time. If he is going to do this withthe set of tasks illustrated above, the tasks can be handled with the followingorder.  

8, 9, 4, 1, 5, 2, 3, 7, 6

And the order below is also possible.

4, 1, 2, 3, 8, 5, 7, 6, 9

But, the order below is not possible.

4, 1, 5, 2, 3, 7, 6, 8, 9

With this order, task 5 is handled earlier that task 8, but inthe precedence relation given in the graph above, task 5 can only begin whentask 8 ends so this order is not possible.

Given V tasks and their precedence relations, write a programthat finds the order by which one person can does one task at a time. Usuallythere are a number of possible orders so all you need to do is present just oneof them. Since a graph with a cycle is not given in input, you don’t need toconsider error-handling in such case. In the graph with no cycle, possibleorder(s) always exist.

输出任务序列

[Constraints]

The total number of vertices, V, in the graph is 5V1000.

Time limit: 1 sec for 10 test cases combined

[Input]

10 test cases are given. Throughout 20 lines, one test case isgiven for every two lines. In the first line of each test case, the totalnumber of graph’s vertices, V, and the total number of edges, E, are given. Inthe next line, E edges are arranged; edges are denoted as comprising twovertices. For example, the edge connecting from vertex 5 to vertex 28 is denotedas “5 28”. The vertex numbers are integers from 1 to V and two neighboringnumbers in the input are separated by a blank space.  

[Output]

Print answers for each of the 10 test cases line-by-linethroughout 10 lines. Start each line with ‘#x’, leave a blank space, and recordthe order of tasks. For the order of tasks, arrange V integers with a blankspace in-between.

[Input/output example]

Input



9 9                             Test case 1 starts 

4 1 1 2 2 3 2 7 5 6 7 6 1 5 8 5 8 9

5 4                             Test case 2 starts

1 2 2 3 4 1 1 5

...

Output(consisting of 10 lines in total)

#1 8 9 4 1 5 2 3 7 6

#2 4 1 2 3 5

...

思路:拓扑排序,这题很没意思,没有做过多的限制,有很多种输出的结果,无法判断程序结果是否正确。

①给出n个点,m条边(n个点分别是1~n发布的,可以充分利用数组下标)

②记录入度和父亲即可,去除父亲节点时,要把孩子的入度减一。(源码及数据下载

错误代码:没有考虑多父亲节点会覆盖的问题

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    freopen("1.txt","r",stdin);
    freopen("2.txt","w",stdout);
    int n,m,x,y;
    while(~scanf("%d%d",&n,&m)){
        //充分利用下标
        int a[10005][2]={0};
        for(int i=0;i<m;i++){
            scanf("%d%d",&x,&y);
            a[y][0]++;   //记录入度
            a[y][1]=x;   //记录父亲
        }
        int visit[10005]={0};
        for(int j=0;j<n;j++){       //依次找到j个点
            int index=0;
            for(int i=1;i<=n;i++){   //找到一个入度为0的点,break
                if(a[i][0]==0&&visit[i]==0){
                    visit[i]=1;
                    index=i;
                    printf("%d ",index);
                    break;
                }
            }
            //遍历哪些点的父亲为index
            for(int i=1;i<=n;i++){
                if(visit[i]==0&&a[i][1]==index) a[i][0]--;
            }
        }
        printf("\n");
    }
    return 0;
}

①用一个二维数组标记,Map[][]表示两者之间存在边的情况,这样空间复杂度和时间复杂度都会高一些。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int Map[1005][1005];
int main(){
    freopen("1.txt","r",stdin);
    freopen("2.txt","w",stdout);
    int n,m,x,y;
    while(~scanf("%d%d",&n,&m)){
        //充分利用下标
        int a[1005]={0};
        for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            Map[i][j]=0;
        for(int i=0;i<m;i++){
            scanf("%d%d",&x,&y);
            a[y]++;   //记录入度
            Map[x][y]=1;
        }
        int visit[1005]={0};
        for(int j=0;j<n;j++){       //依次找到j个点
            int index=0;
            for(int i=1;i<=n;i++){   //找到一个入度为0的点,break
                if(a[i]==0&&visit[i]==0){
                    visit[i]=1;
                    index=i;
                    printf("%d ",index);
                    break;
                }
            }
            //遍历哪些点的父亲为index
            for(int i=1;i<=n;i++){
                if(visit[i]==0&&Map[index][i]==1) a[i]--;
            }
        }
        printf("\n");
    }
    return 0;
}

②在原基础上,用一个vector存储所用的孩子节点,然后删除当前父节点的所有孩子节点。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> V[1005];
int main(){
    freopen("1.txt","r",stdin);
    freopen("2.txt","w",stdout);
    int n,m,x,y;
    while(~scanf("%d%d",&n,&m)){
        //充分利用下标
        int a[1005]={0};
        for(int i=0;i<m;i++){
            scanf("%d%d",&x,&y);
            a[y]++;   //记录入度
            V[x].push_back(y);
        }
        int visit[1005]={0};
        for(int j=0;j<n;j++){       //依次找到j个点
            int index=0;
            for(int i=1;i<=n;i++){   //找到一个入度为0的点,break
                if(a[i]==0&&visit[i]==0){
                    visit[i]=1;
                    index=i;
                    printf("%d ",index);
                    break;
                }
            }
            //遍历哪些点的父亲为index
            for(int i=0;i<V[index].size();i++){
                a[V[index][i]]--;
            }
            V[index].clear();
        }
        printf("\n");
    }
    return 0;
}

③队列,第一步存储所有入度为0的结点,第二步依次把相连的结点入度减1,且满足条件入队。

参考代码

  • 6
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Python 上机库是一种集合了各种难度级别的 Python 编程目的资源。它主要用于帮助学习者在实践中巩固和提高他们的 Python 编程能力。上机库可以包含不同类型的目,例如算法、数据结构、面向对象编程等。 Python 上机库的应用非常广泛。对于初学者来说,通过做目可以加深对 Python 语言基础知识的理解,掌握基本的编码技巧,提高编程思维能力。对于进阶者来说,通过解决更加复杂的问和挑战,可以拓宽知识面并提高解决问的能力。同时,上机库还可以作为考试和面试准备的工具,帮助学习者了解应用场景和解决实际问的能力。 一个好的上机库需要具备以下特点:目涵盖广泛,包括各个主和难度级别;有详细的目描述和输入输出要求,使学习者能够清晰地理解问和解思路;提供测试用例,方便学习者验证代码的正确性;给出参考答案和思路解析,帮助学习者分析和理解优质的解决方法。 Python 上机库的使用方法也比较简单。学习者可以根据自己的水平选择合适的目进行练习。在解过程中,可以通过尝试不同的思路和算法,提高解决问的策略;也可以参考目的参考答案,学习别人的解决思路和编码技巧,从中汲取经验。此外,可以尝试与他人合作完成一些复杂的目,通过交流和讨论来共同提高。 总之,Python 上机库是一个非常有价值的学习资源,可以帮助学习者提高 Python 编程能力、应对复杂问和提升解决问的能力。通过不断练习和实践,学习者能够逐渐掌握更加高级的编程技能,为未来的学习和工作打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值