1. 程式人生 > >ACM/ICPC 2018亞洲區預選賽北京賽站網路賽 Tomb Raider

ACM/ICPC 2018亞洲區預選賽北京賽站網路賽 Tomb Raider

時間限制:1000ms

單點時限:1000ms

記憶體限制:256MB

描述

Lara Croft, the fiercely independent daughter of a missing adventurer, must push herself beyond her limits when she discovers the island where her father disappeared. In this mysterious island, Lara finds a tomb with a very heavy door. To open the door, Lara must input the password at the stone keyboard on the door. But what is the password? After reading the research notes written in her father's notebook, Lara finds out that the key is on the statue beside the door.

The statue is wearing many arm rings on which some letters are carved. So there is a string on each ring. Because the letters are carved on a circle and the spaces between any adjacent letters are all equal, any letter can be the starting letter of the string. The longest common subsequence (let's call it "LCS") of the strings on all rings is the password. A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.

For example, there are two strings on two arm rings: s1 = "abcdefg" and s2 = "zaxcdkgb". Then "acdg" is a LCS if you consider 'a' as the starting letter of s1, and consider 'z' or 'a' as the starting letter of s2. But if you consider 'd' as the starting letter of s1 and s2, you can get "dgac" as a LCS. If there are more than one LCS, the password is the one which is the smallest in lexicographical order.

Please find the password for Lara.

輸入

There are no more than 10 test cases.

In each case:

The first line is an integer n, meaning there are n (0 < n ≤ 10) arm rings.

Then n lines follow. Each line is a string on an arm ring consisting of only lowercase letters. The length of the string is no more than 8.

輸出

For each case, print the password. If there is no LCS, print 0 instead.

樣例輸入

2
abcdefg
zaxcdkgb
5
abcdef
kedajceu
adbac
abcdef
abcdafc
2
abc
def

樣例輸出

acdg
acd
0

 

題意

有n個字串,每個字串首尾相連,求這n個字串的最長公共子序列並輸出

思路

將每個首尾相連字串從0~len-1的每個位置形成的字串都進行二進位制列舉,將所有情況的子序列都用map標記並統計出現的次數,然後列舉map裡的元素,將出現n次的子序列存進vector,對vector裡的元素進行排序。排序的規則:如果兩個子序列長度不同,返回長度較長的子序列,如果相同,返回字典序小的子序列

複雜度大概是10*8*8*(2的8次方)大概為2的17次方131072!!!暴力可以做的

//其中確實有很多用法值得推敲
//用dev編譯器上auto不知道為什麼報錯??兩個問題留在這裡
#include "bits/stdc++.h" 


using namespace std;
map<string ,int> mp,vis;
vector<string> vec;
string m,s,str;
void change(int pos)
{
	str.clear();
	string tmp;
	tmp=m.substr(pos);
	str+=tmp;
	tmp=m.substr(0,pos);
	str+=tmp;
}
bool cmp(const string &a,const string &b)
{
	if(a.length()!=b.length())
	{
		return a.length()>b.length();//簡單的理解就是不管如何返回a
		//a是大的就返回大的,a是小的就返回小的 
	}
	else
	{
		return a<b;// 
	}
} 
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		mp.clear();
		vec.clear();
		int nn=n;
		while(nn--)
		{
			vis.clear();//資料型別多的時候,初始化一定要記住 
			cin>>m;
			int len=m.length();
			for(int i=0;i<=len-1;i++)
			{
				change(i);
				for(int j=1;j<(1<<len);j++)//j不能等於(1<<len)
				// 臥槽,太容易錯了 !!!mmp難受 ,不懂為什麼??? 
				{
					for(int k=0;k<len;k++)
					{
						if((j>>k)&1)
						s+=str[k];
					}
					if(vis[s]==0)
					{
						mp[s]++;
						vis[s]=1;
					}
					s.clear();
				}
			}
		}
		int flag=0;
		for(auto i: mp)
		{
			if(i.second==n)
			{
				vec.push_back(i.first);
				flag=1;
			}
		}
		sort(vec.begin(),vec.end(),cmp);//第三個引數用來自定義排序方式 
		if(flag==0)
		cout<<0<<endl;
		else
		cout<<vec[0]<<endl;
	}
	
	return 0;
}

 真菜啊!!真難啊!!