H: Legacy Code (2015 German Collegiate Programming Contest (GCPC 15) + POI 10-T3)

Once again you lost days refactoring code, which never runs in the first place. Enough is enough
– your time is better spent writing a tool that finds unused code!
Your software is divided into packages and executables. A package is a collection of meth-
ods. Executables are packages defining among other methods exactly one method with name
PROGRAM. This method is executed on the start of the corresponding executable. Ordinary
packages have no method named PROGRAM.
Each method is uniquely identified by the combination of package and method names. E.g.
the method with the identifier SuperGame::PROGRAM would be the main method of the
executable SuperGame.
For every method in your software you are given a list of methods directly invoking it. Thus you
can easily identify methods, that are never called from any method. However, your task is more
challenging: you have to find unused methods. These are methods that are never reached by the
control flow of any executable in your software.
Input
The first line of the input contains an integer N , the number of methods in your software
(1 ≤ N ≤ 400).
Each method is described by two lines, totaling in 2 · N lines. The first line consists of the unique
identifier of the method and ki, the number of methods directly invoking this one (0 ≤ ki ≤ N ).
The second line consists of a set of ki identifiers of these calling methods or is empty if there are
no such methods, i.e. ki = 0.
Method identifiers consist of a package name followed by two colons and a method name
like Packagename::Methodname. Both strings, the package and the method name, each
consist of up to 20 lowercase, uppercase characters or digits (a-z, A-Z, 0-9).
There will be exactly N different method identifiers mentioned in the input.
Output
A line containing the number of unused methods in your software.
Sample Input 1 Sample Output 1
2
SuperGame::PROGRAM 0
HelpPackage::HelpFunction 2
HelpPackage::HelpFunction SuperGame::PROGRAM
0
Sample Input 2 Sample Output 2
2
Loop::CallA 1
Loop::CallB
Loop::CallB 1
Loop::CallA
2
GCPC 2015 – Problem H: Legacy Code 15Sample Input 3 Sample Output 3
2
SuperGame::PROGRAM 1
SuperServer42::PROGRAM
SuperServer42::PROGRAM 1
SuperServer42::PROGRAM
0

题意:对于每个方法如果有被其他方法调用就依次给出调用该方法的方法,题目要求没有运行的方法即没有直接或间接被“::PROGRAM”调用的方法;

思路:可以将每个方法哈希一下变成一个整数,这样就可以利用整数值建图,然后利用类似于求最短路的方法将所有主方法加入队列跑一遍就可以了

步骤:

        1、读入每个方法的同时进行哈希,然后建一条从调用方法到被调用方法的边

        2、将所有点的距离初始化为INF,遍历所有点将主方法加入队列,距离变为0,跑一遍算法

        3、遍历所有点,每遇到一个距离为INF的点答案加一

AC代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;

const int N=410,M=300010,INF=0x3f3f3f3f;

int n,id;
int dist[N];
bool st[N];
int h[N],ne[M],e[M],idx;
map<string,int> mp;
string str="::PROGRAM";

void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

bool check(string s)//判断主方法
{
	int n=s.size();
	if(n<=9)return 0;
	return str==s.substr(n-9);
}

void bfs()
{
	queue<int>q;
	memset(dist,0x3f,sizeof dist);
	for(int i=1;i<=id;i++)
		if(st[i])
		{
			q.push(i);
			dist[i]=0;
		}
	
	while(q.size())
	{
		int t=q.front();
		q.pop();
		for(int i=h[t];~i;i=ne[i])
		{
			int j=e[i];
			if(dist[j]==INF)
			{
				dist[j]=dist[t]+1;
				q.push(j);
			}
		}
	}
}

int main()
{
	memset(h,-1,sizeof h);
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		string s;
		int m;
		cin>>s>>m;
		if(!mp.count(s))
		{
			mp[s]=++id;
			st[id]=check(s);
		}
		for(int j=0;j<m;j++)
		{
			string ss;
			cin>>ss;
			if(!mp.count(ss))
			{
				mp[ss]=++id;
				st[id]=check(ss);
			}
			add(mp[ss],mp[s]);
		}
	}
	
	bfs();
	
	int res=0;
	for(int i=1;i<=id;i++)
		res+=(dist[i]==INF);
	printf("%d\n",res);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Double.Qing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值