首页 > 试题广场 >

最长句子

[编程题]最长句子
  • 热度指数:619 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
英语中,有些单词可以出现在其他单词后面。例如“Love”可以出现在“I”之后,“You”可以出现在“Love”之后,因此它们能构成“I Love You”这句话。
现在给你一些单词间的关系,你能计算出最多能有几个单词组合在一起构成一句话吗?

输入描述:
输入包含多组数据。

每组数据的第一行包含一个正整数n (1≤n≤10000)。

紧接着n行单词关系,每行包含两个单词A和B,表示单词B能出现在A后面。单词长度不超过32个字符,并且只有字母组成。

不存在循环的依赖关系。


输出描述:
对应每组数据,输出最多有几个单词能构成一个句子。
示例1

输入

1
hello world
3
I love
love you
love me

输出

2
3
#include<map>
#include<vector>
#include<string>
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
map<string,vector<string> > G;
map<string,int> dp;
int d(string);
int main(){
	int N,i;
	while(cin>>N){
		G.clear();
		dp.clear();
		set<string> s;
		for(i=0;i<N;i++){
			string x,y;
			cin>>x>>y;
			G[x].push_back(y);
			s.insert(x),s.insert(y);
		}
		int Max=0;
		set<string>::iterator it;
		for(it=s.begin();it!=s.end();it++)
			Max=max(Max,d(*it));
		printf("%d\n",Max);
	}
}
int d(string x){
	if(dp.count(x)) return dp[x];
	dp[x]=1;
	vector<string> &dict=G[x];
	int i;
	for(i=0;i<dict.size();i++)
		dp[x]=max(dp[x],d(dict[i])+1);
	return dp[x];
}//DAG上的动态规划,用map代替数组来实现dp

发表于 2017-08-28 13:45:18 回复(0)
java版本代码 动态规划
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; /**  * Created by mengfanshan on 2017/7/18.  * 英语中,有些单词可以出现在其他单词后面。例如“Love”可以出现在“I”之后,“You”可以出现在“Love”之后,因此它们能构成“I Love You”这句话。  现在给你一些单词间的关系,你能计算出最多能有几个单词组合在一起构成一句话吗?  输入描述:  输入包含多组数据。   每组数据的第一行包含一个正整数n (1≤n≤10000)。   紧接着n行单词关系,每行包含两个单词A和B,表示单词B能出现在A后面。单词长度不超过32个字符,并且只有字母组成。   不存在循环的依赖关系。  输出描述:  对应每组数据,输出最多有几个单词能构成一个句子。  示例1  输入   1  hello world  3  I love  love you  love me  输出   2  3   思路:使用图的最短路径算法,找到距离最长的两个点(不包含两个点之间不连通的情况)  */ public class zuichangjuzi { public static int getLongestPath(int[][] array)
    { int[] distince=new int[array.length]; for (int i=0;i<array.length;i++)
        { int rudu=0; for (int j=0;j<array.length;j++)
            { if(array[j][i]==1)
                {
                    rudu=rudu+array[j][i];
                }
            }
            distince[i]=rudu;
        }
        Queue<Integer> _zeroQueue=new LinkedList<>(); for (int i=0;i<distince.length;i++)
        { if(distince[i]==0)
            {
                _zeroQueue.add(i);
                distince[i]=-1;
            }
        } //存储末尾节点为i的最长路径的长度  int[] maxpath=new int[array.length]; while (!_zeroQueue.isEmpty())
        { int node = _zeroQueue.poll(); //System.out.println("node="+node);  //减少这个点连接的点的入度  for (int i=0;i<distince.length;i++)
            { if(array[node][i]>0)
                {
                    distince[i]=distince[i]-1;
                } //System.out.println("distince="+distince[i]);  if(distince[i]==0)
                {
                    _zeroQueue.add(i);
                    distince[i]=-1;
                }
            } int max=0; for (int j = 0; j < array.length; j++) { if (array[j][node] == 1) { if(maxpath[j]+1>max)
                    {
                        max=maxpath[j]+1;
                    }
                }
            }
            maxpath[node]=max;

        } int max=0; for (int i=0;i<maxpath.length;i++)
        { if(maxpath[i]>max)
            {
                max=maxpath[i];
            } //System.out.println(maxpath[i]);  } return max;
    } static int maxvalue=100000; public static void main(String[] args)throws IOException
    {

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
        String l=bufferedReader.readLine(); while (l!=null)
        { int sentencecount=Integer.valueOf(l);
            ArrayList<String> sentencelist=new ArrayList<>();
            ArrayList<String> wordlist=new ArrayList<>(); for (int i=0;i<sentencecount;i++)
            {
                String s=bufferedReader.readLine();
                sentencelist.add(s);
                String[] var=s.split(" "); for (int j=0;j<var.length;j++)
                { if(!wordlist.contains(var[j]))
                    {
                        wordlist.add(var[j]);
                    }
                }
            } int[][] array=new int[wordlist.size()][wordlist.size()]; for (int i=0;i<sentencecount;i++)
            {
                String line=sentencelist.get(i);
                String[] var=line.split(" "); int index1=wordlist.indexOf(var[0]); int index2=wordlist.indexOf(var[1]); //   System.out.println("index1="+index1+","+index2+","+line+","+var[0]+","+var[1]);  array[index1][index2]=1;
            }
            System.out.println("wordlist="+wordlist); for (int i=0;i<array.length;i++)
            { for (int j=0;j<array.length;j++)
                {
                    System.out.print(array[i][j]+" ");
                }
                System.out.println();
            } int max =getLongestPath(array);

            System.out.println(max+1);
            l=bufferedReader.readLine();
        }
    }
}
发表于 2017-07-19 13:05:28 回复(0)
不断的遍历入度为0的节点,直至所有节点都被遍历。
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <exception>
#include <iomanip>
#include <memory>
#include <sstream>

using namespace std;

int main(int argc, char** argv)
{
	int n;
	while (cin >> n && n >= 1 && n <= 10000)
	{
		unordered_map<string, int> hs;
		unordered_map<int, vector<int>> graph;
		unordered_map<int, int> inDegree;
		for (int i = 0; i < n; ++i)
		{
			string from, to;
			cin >> from >> to;
			if (hs.find(from) == hs.end())
			{
				hs.emplace(from, hs.size());
				inDegree[hs[from]] = 0;
			}
			if (hs.find(to) == hs.end())
			{
				hs.emplace(to, hs.size());
				inDegree[hs[to]] = 0;
			}
			graph[hs[from]].emplace_back(hs[to]);
			++inDegree[hs[to]];
		}

		int maxLen = 1;
		while (true)
		{
			unordered_map<int, int> next;
			for (auto& pr : inDegree)
			{
				if (pr.second == 0)
				{
					--pr.second;
					for (auto& i : graph[pr.first]) ++next[i];
				}
			}
			if (next.empty()) break;
			++maxLen;
			for (auto& pr : next) inDegree[pr.first] -= pr.second;
		}

		cout << maxLen << endl;
	}

	return 0;
}

发表于 2017-07-10 21:38:10 回复(0)
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        while (sc.hasNext()) {
            Map<String, List<String>> mapper = new HashMap<>();
            int k = sc.nextInt();

            for (int i = 0; i < k; i++) {
                String from = sc.next();
                String to = sc.next();

                if (!mapper.containsKey(from)) {
                    mapper.put(from, new ArrayList<>());
                }
                if (!mapper.containsKey(to)) {
                    mapper.put(to, new ArrayList<>());
                }
                mapper.get(from).add(to);
            }

            int max = -1;
            Map<String, Integer> save = new HashMap<>();
            for (String s : mapper.keySet()) {
                int temp = dp(save, mapper, s);
                if (temp > max) {
                    max = temp;
                }
            }
            System.out.println(max);
        }
    }

    private static int dp(Map<String, Integer> save, Map<String, List<String>> mapper, String s) {
        if (mapper.get(s).isEmpty()) {
            return 1;
        }

        if (!save.containsKey(s)) {
            int max = -1;
            for (String ss : mapper.get(s)) {
                int temp = dp(save, mapper, ss) + 1;
                if (temp > max)
                    max = temp;
            }
            save.put(s, max);
        }
        return save.get(s);
    }
}
动态规划求解
发表于 2018-08-22 14:50:38 回复(0)
拓扑排序求有向无环图中的最长路径。
http://www.geeksforgeeks.org/find-longest-path-directed-acyclic-graph/
发表于 2016-03-05 12:29:51 回复(0)
这题转换成节点为string的有向图,一对单词是图的一个有向边。问题就转变为求此图的关键路径问题了。
发表于 2015-12-16 10:32:20 回复(0)
用set和map可以很轻松的解决

#include <set>
#include <map>
#include <string>
#include <iostream>
using namespace std;
int getLen(string s,map<string,set<string>>& mp,map<string,int>& hasFind){
if(hasFind.count(s)==1)
return hasFind[s];
if(mp.count(s)==0)
return 1;
int len=0;
int max=0;
for(set<string>::iterator iter=mp[s].begin();iter!=mp[s].end();iter++)
{
len=1+getLen(*iter,mp,hasFind);
if(len>max)
max=len;
}
hasFind[s]=max;
return max;
}
int main(){
    string s1,s2;
    int n;
    while(cin>>n){
        map<string,set<string>> mp;
map<string,int> hasFind;
        while(n-->0){
        cin>>s1>>s2;
         mp[s1].insert(s2);
        }
        int max=0;
int len;
for(map<string,set<string>>::iterator it=mp.begin();it!=mp.end();it++){
if((len=getLen(it->first,mp,hasFind))>max)
max=len;
}
        cout<<max<<endl;
    }
    return 0;
}
发表于 2015-11-13 17:26:28 回复(0)