POJ3007--Organize Your Train part II

Description

RJ Freight, a Japanese railroad company for freight operations has recently constructed exchange lines at Hazawa, Yokohama. The layout of the lines is shown in Figure 1.


Figure 1: Layout of the exchange lines

A freight train consists of 2 to 72 freight cars. There are 26 types of freight cars, which are denoted by 26 lowercase letters from "a" to "z". The cars of the same type are indistinguishable from each other, and each car's direction doesn't matter either. Thus, a string of lowercase letters of length 2 to 72 is sufficient to completely express the configuration of a train.

Upon arrival at the exchange lines, a train is divided into two sub-trains at an arbitrary position (prior to entering the storage lines). Each of the sub-trains may have its direction reversed (using the reversal line). Finally, the two sub-trains are connected in either order to form the final configuration. Note that the reversal operation is optional for each of the sub-trains.

For example, if the arrival configuration is "abcd", the train is split into two sub-trains of either 3:1, 2:2 or 1:3 cars. For each of the splitting, possible final configurations are as follows ("+" indicates final concatenation position):

  [3:1]
    abc+d  cba+d  d+abc  d+cba
  [2:2]
    ab+cd  ab+dc  ba+cd  ba+dc  cd+ab  cd+ba  dc+ab  dc+ba
  [1:3]
    a+bcd  a+dcb  bcd+a  dcb+a

Excluding duplicates, 12 distinct configurations are possible.

Given an arrival configuration, answer the number of distinct configurations which can be constructed using the exchange lines described above.

Input

The entire input looks like the following.

the number of datasets = m
1st dataset
 
2nd dataset 
... 
m-th dataset

Each dataset represents an arriving train, and is a string of 2 to 72 lowercase letters in an input line.

Output

For each dataset, output the number of possible train configurations in a line. No other characters should appear in the output.

Sample Input

4
aa
abba
abcd
abcde

Sample Output

1
6
12
18
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define maxn 300
int sum;
vector <int> ans[maxn+10];
void Strcat(char *a,char *b,char *str)//把a和b连起来,存到str
{
	int len=strlen(a);
	for(int i=0;i<len;i++)
	{
		str[i]=a[i];
	}
	int len1=strlen(b);
	for(int i=len;i<len+len1;i++)
	{
		str[i]=b[i-len];
	}
	str[len+len1]='\0';
}
void Hash(char *s)
{
	int len=strlen(s);
	int anss=0;
	int bnss=0;
	for(int i=0;i<len;i++)
	{
		anss=(anss*43+s[i])%307;
		bnss=(bnss*293+s[i])%558661;
	}
	int key=anss;
	if(!ans[key].size())
	{
		ans[key].push_back(bnss);
		sum++;
	}
	else
	{
		bool flag=true;
		for(int j=0;j<ans[key].size();j++)
		{
			if(!(ans[key][j]^bnss))
			{
				flag=false;
				break;
			}
		}
		if(flag)
		{
			ans[key].push_back(bnss);
			sum++;
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	char str[80];
	while(t--)
	{
		sum=0;
		int z;
		for(int i=0;i<maxn+3;i++)
		{
			ans[i].clear();
		}
		char T[80];
		scanf("%s",T);
		int len=strlen(T);
		if(len==1)
		{
			printf("%d\n",1);
			goto L;
		}
		for(int i=0;i<len-1;i++)
		{
			char A[80],B[80],C[80],D[80];
			for(int j=0;j<=i;j++)
			{
				A[j]=T[j];
			}
			A[i+1]='\0';//这里不会错
			z=i;
			for(int j=0;j<=i;j++)
			{
				B[j]=T[z--];
			}
			B[i+1]='\0';//这里也不会错
			for(int j=0;j<len-i-1;j++)
			{
				C[j]=T[j+i+1];
			}
			C[len-i-1]='\0';
			z=0;
			for(int j=len-1;j>=i+1;j--)
			{
				D[z++]=T[j];
			}
			D[z]='\0';//我擦, 字符串的处理都不会错啊
			Strcat(A,C,str);
			Hash(str);
			Strcat(A,D,str);
			Hash(str);
			Strcat(B,C,str);
			Hash(str);
			Strcat(B,D,str);
			Hash(str);
			Strcat(C,A,str);
			Hash(str);
			Strcat(C,B,str);
			Hash(str);
			Strcat(D,A,str);
			Hash(str);
			Strcat(D,B,str);
			Hash(str);
		}
		printf("%d\n",sum);
		L:;
	}
	return 0;
}

为什么这样就会WA呢??擦。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define maxn 400
int sum=0;
struct Node
{
	bool vis;
	int key;//用一个值来代替一个字符串。两个哈希的妙处,字符串的比较相等没有数字快
	Node * next;
}word[maxn];
//总共大概600种情况。所以只需要模600这里的素数就行了
void Strcat(char *a,char *b,char *str)//把a和b连起来,存到str。。这里肯定不会错。因为我AC代码这里是一样的
{
	int len=strlen(a);
	for(int i=0;i<len;i++)
	{
		str[i]=a[i];
	}
	int len1=strlen(b);
	for(int i=len;i<len+len1;i++)
	{
		str[i]=b[i-len];
	}
	str[len+len1]='\0';
}
void Hash(char * s)//错的地方只可能是这里。其他地方我没动过。一个哈希以及两个哈希vector做法都AC。就是用链表WA
{
	int len=strlen(s);
	int ans1=0,ans2=0;
	for(int i=0;i<len;i++)
	{
		ans1=(ans1*43+s[i])%307;
		ans2=(ans2*293+s[i])%558661;//这两个哈希函数跟我AC的代码一样的、
	}
	if(!word[ans1].vis)
	{
		word[ans1].vis=1;
		word[ans1].key=ans2;
		word[ans1].next=NULL;
		sum++;
	}
	else
	{
		bool flag=false;//false表示找不到一样的
		Node * p = &word[ans1];
		while(p!=NULL)
		{
			if(p->key == ans2)
			{
				flag=true;
				break;
			}
			p = p->next;
		}
		if(!flag)
		{
			p=new Node();
			p->key = ans2;
			p->next = NULL;
			sum++;				
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	char str[80];
	while(t--)
	{
		memset(word,0,sizeof(word));
		sum=0;
		int z;
		char T[80];
		scanf("%s",T);
		int len=strlen(T);
		if(len==1)
		{
			printf("%d\n",1);
			goto L;
		}
		for(int i=0;i<len-1;i++)
		{
			char A[80],B[80],C[80],D[80];
			for(int j=0;j<=i;j++)
			{
				A[j]=T[j];
			}
			A[i+1]='\0';//这里不会错
			z=i;
			for(int j=0;j<=i;j++)
			{
				B[j]=T[z--];
			}
			B[i+1]='\0';//这里也不会错
			for(int j=0;j<len-i-1;j++)
			{
				C[j]=T[j+i+1];
			}
			C[len-i-1]='\0';
			z=0;
			for(int j=len-1;j>=i+1;j--)
			{
				D[z++]=T[j];
			}
			D[z]='\0';//我擦, 字符串的处理都不会错啊
			Strcat(A,C,str);
			Hash(str);
			Strcat(A,D,str);
			Hash(str);
			Strcat(B,C,str);
			Hash(str);
			Strcat(B,D,str);
			Hash(str);
			Strcat(C,A,str);
			Hash(str);
			Strcat(C,B,str);
			Hash(str);
			Strcat(D,A,str);
			Hash(str);
			Strcat(D,B,str);
			Hash(str);
		}
		printf("%d\n",sum);
L:;
	}
	return 0;
}


字典树会超时???擦

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int cnt;
void Strcat(char *a,char *b,char *str)//把a和b连起来,存到str
{
	int len=strlen(a);
	for(int i=0;i<len;i++)
	{
		str[i]=a[i];
	}
	int len1=strlen(b);
	for(int i=len;i<len+len1;i++)
	{
		str[i]=b[i-len];
	}
	str[len+len1]='\0';
}
struct Node
{
	Node * pr[26];
	int id;
	Node()
	{
		id=0;
		memset(pr,0,sizeof(pr));
	}
}*root;
int idx(char c)
{
	return c-'a';
}
void insert(char * s)
{
	int len=strlen(s);
	Node * p=root;
	for(int i=0;i<len;i++)
	{
		int u=idx(s[i]);
		if(p->pr[u]==NULL)
		{
			p->pr[u]=new Node();
		}
		p=p->pr[u];
	}
	if(p->id==0)
	{
		p->id=cnt++;
	}
}
void del(Node * p)
{
	for(int i=0;i<26;i++)
	{
		if(p->pr[i])del(p->pr[i]);
	}
	delete p;
	p=NULL;
}
int main()
{
	int t;
	scanf("%d",&t);
	char T[80];
	while(t--)
	{
		char str[80];
		int z;
		cnt=1;
		root=new Node();
		scanf("%s",T);
		int len=strlen(T);
		for(int i=0;i<len-1;i++)
		{
			char A[80],B[80],C[80],D[80];
			for(int j=0;j<=i;j++)
			{
				A[j]=T[j];
			}
			A[i+1]='\0';//这里不会错
			z=i;
			for(int j=0;j<=i;j++)
			{
				B[j]=T[z--];
			}
			B[i+1]='\0';//这里也不会错
			for(int j=0;j<len-i-1;j++)
			{
				C[j]=T[j+i+1];
			}
			C[len-i-1]='\0';
			z=0;
			for(int j=len-1;j>=i+1;j--)
			{
				D[z++]=T[j];
			}
			D[z]='\0';//我擦, 字符串的处理都不会错啊
			Strcat(A,C,str);
			insert(str);
			Strcat(A,D,str);
			insert(str);
			Strcat(B,C,str);
			insert(str);
			Strcat(B,D,str);
			insert(str);
			Strcat(C,A,str);
			insert(str);
			Strcat(C,B,str);
			insert(str);
			Strcat(D,A,str);
			insert(str);
			Strcat(D,B,str);
			insert(str);
		}
		del(root);
		printf("%d\n",cnt-1);
	}
	return 0;
}


 


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值