网易互娱2017实习生招聘在线笔试--源代码编译

描述
在网易游戏的日常工作中,C++ 是一门常用的语言。面对众多的 C++ 代码,等待源文件编译的漫长时间是个令人糟心的时刻,一直以来大家对此怨声载道。终于有一天,大家找到了你,一位优秀的程序员,请你来帮忙分析一下编译速度的瓶颈。
经过一番调查和研究,你发现一些源代码之间是有依赖关系的。例如,某个源文件 a.cpp 编译链接生成了动态链接库 a.dll,而 b.cpp 编译链接生成的 b.dll 依赖于 a.dll。这个时候,必须等待 a.dll 生成之后才能生成 b.dll。为了表达简单,我们这个时候称 b.cpp 依赖于 a.cpp。
网易游戏内部使用了一个分布式并行的编译平台,可以同时编译多个不互相依赖的文件,大大提高了源代码的编译速度。然而当某些依赖链很长的时候,这个编译平台也无能为力,只能按照依赖顺序一个一个完成编译,从而造成了很长的编译时间。
为了验证这个想法,你决定着手通过代码分析这些文件之间的编译顺序。已知这些文件的文件名,以及这些文件所依赖的其他文件,你需要编写一个程序,输出一个可行的编译所有源文件的编译顺序。如果有多种可行的序列,请输出所有文件名序列中字典序最小的那一个(序列 (a1, a2, ..., an) 字典序小于序列 (b1, b2, ..., bn),当且仅当存在某个 i ,使得 ai 的字典序小于 bi,并且对于任意 j < i ,都有 aj = bj)。
输入
输入包含多组测试数据。
输入的第一行包含一个整数 T(T ≤ 100),表示输入中一共包含有 T 组测试数据。
每组测试数据第一行是一个整数 N(N ≤ 1000),表示一共有 N 个源代码文件。随后一共有 N 行数据,其中第 i(0 ≤ i < N) 行数据包含序号为 i 的源代码文件的依赖信息。每一行开头是一个字符串,表示这一个文件的文件名,随后一个整数 m(0 ≤ m ≤ N),表示编译这个源文件之前需要先编译 m 个依赖文件。之后是 m 个整数 j0 ... jm-1,表示这 m 个依赖文件的序号(0 ≤ j < N) 。所有的文件名仅由小写字母、数字或“.”组成,并且不会超过 10 个字符。保证 n 个源代码文件的文件名互不相同。
输出
对于每一组输入,按照编译先后顺序输出一组可行的编译顺序,一行一个文件名。如果有多种可行的序列,请输出所有文件名序列中字典序最小的那一个。如果不存在可行的编译顺序,输出一行 ERROR。每组测试数据末尾输出一个空行。
样例输入
3
2
a.cpp 0
b.cpp 1 0
2
cb 0
c 0
2
a.cpp 1 1
b.cpp 1 0
样例输出
a.cpp
b.cpp


c
cb


ERROR
这个题思路也比较明显,拓扑排序,有环的时候就是ERROR。由于要按照字典序输出,所以还要排序。

  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <sstream>
  7 
  8 using namespace std;
  9 
 10 void cacIndgeee(vector<vector<int>> &G,vector<int>& inde)
 11 {
 12     for(int i=0;i<G.size();i++)
 13     {
 14         vector<int> gv=G[i];
 15         for(int j=0;j<gv.size();j++)
 16         {
 17             inde[gv[j]]++;
 18         }
 19     }
 20 }
 21 
 22 int main()
 23 {
 24     int T,N;
 25     int m,t,s;
 26     string fname;
 27     cin>>T;
 28     ostringstream os;
 29     for(int i=0;i<T;i++)
 30     {
 31         vector<string> file;
 32         map<string,int> mapIndex;
 33         cin>>N;
 34         bool noError=true;
 35         priority_queue<string,vector<string>,greater<string>> q;
 36         int count =0;
 37         vector<string> vresult;
 38         vector<vector<int>> G(N);
 39         vector<int> indegree(N,0);
 40         for(int j=0;j<N;j++)
 41         {
 42             count =0;
 43             cin>>fname>>m;
 44             file.push_back(fname);
 45             mapIndex[fname]=j;
 46             for(int k=0;k<m;k++)
 47             {
 48                 cin>>t;
 49                 G[t].push_back(j);
 50             }
 51         }
 52         cacIndgeee(G,indegree);
 53         for(int j=0;j<N;j++)
 54         {
 55             if(!indegree[j])
 56             {
 57                q.push(file[j]);
 58             }
 59         }
 60         while(!q.empty())
 61         {
 62             s=mapIndex[q.top()];
 63             q.pop();
 64             count++;
 65             vector<int> gv=G[s];
 66             vresult.push_back(file[s]);
 67             for(int k=0;k<gv.size();k++)
 68             {
 69                 int r=gv[k];
 70                 --indegree[r];
 71                 if(!indegree[r])
 72                     q.push(file[r]);
 73             }
 74         }
 75         if(count<N)
 76         {
 77             noError= false;
 78         }
 79         if(!noError)
 80         {
 81             os<<"ERROR"<<endl;
 82         }
 83         else
 84         {
 85             for(int i=0;i<vresult.size();i++)
 86             {
 87                 os<<vresult[i]<<endl;;
 88             }
 89         }
 90         os << endl;
 91     }
 92     cout<<os.str();
 93     return 0;
 94 }
 95 /*
 96 1
 97 5
 98 11.cpp 0
 99 33.cpp 1 0
100 22.cpp 1 0
101 44.cpp 1 2
102 55.cpp 2 1 3
103 
104 1
105 7
106 aa 0
107 bb 1 0
108 cc 1 0
109 ff 1 0
110 dd 1 1
111 ee 2 2 3
112 gg 2 4 5
113 */

 

posted @ 2016-09-17 15:33  wjliu  阅读(779)  评论(0)    收藏  举报