poj-3007-Organize Your Train part II

Organize Your Train part II
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8421 Accepted: 2407

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

Source




题目大意:

把 一个字符串分割成两部分,然后拼接成一个新串,求可以形成多少种不同的串。


题解:

这题字符串的获取还是很简单的,由于字符串长度不超过72,所以直接暴力就可以了。坑在于统计不同的字符串的个数时的操作。

一开始图简单直接map,发现TLE不可水过,所以之能另辟蹊径了,首先想到的是字典树,然而第一发就MLE   TMT,

然后想了想应该是节点申请没delete所以写了个函数在每次操作结束后释放内存,结构TLE了有,渀溃,一上午就MLE,TLE中渀溃度过QAQ。

后面皮比君说了他以前也这样,要静态字典树才可破,然后就开始了捣鼓,然后才过的,My God!!!


AC 代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;
int sum,top;

struct node{
	bool flag;
	int next[26];
}p[100086];

void Init(int x){//初始化节点
	memset(p[x].next,-1,sizeof(p[x].next));
	p[x].flag = false;
}

void Search(int x,char str[]){//查找&&添加节点
	int len = strlen(str);
	for(int i = 0; i < len; i++){
		if(p[x].next[str[i]-'a'] < 0){
			p[x].next[str[i]-'a'] = top;
			Init(top++);
		}
		x = p[x].next[str[i]-'a'];
	}
	if(p[x].flag == false){
		p[x].flag = true;
		sum++;
	}
}

int main(){
	int n;
	scanf("%d",&n);
	while(n--){
		top = sum = 0;
		Init(top++);
		char str[80];
		scanf("%s",str);
		int len = strlen(str);
		for(int d = 1; d < len; d++){//获取四个小字符串
			char str1[80];
			char str2[80];
			char str3[80];
			char str4[80];

			for(int j = 0; j < d; j++)
				str1[j] = str[j];
			str1[d] = '\0';

			for(int j = 0; j < d; j++)
				str2[j] = str1[d-j-1];
			str2[d] = '\0';

			for(int j = 0; j < len-d; j++)
				str3[j] = str[d+j];
			str3[len-d] = '\0';

			for(int j = 0; j < len-d; j++)
				str4[j] = str3[len-d-j-1];
			str4[len-d] = '\0';

			char str5[80];//合成的字符串
			strcpy(str5,str1);
			strcat(str5,str3);
			Search(0,str5);

			strcpy(str5,str1);
			strcat(str5,str4);
			Search(0,str5);

			strcpy(str5,str2);
			strcat(str5,str3);
			Search(0,str5);

			strcpy(str5,str2);
			strcat(str5,str4);
			Search(0,str5);
			
			strcpy(str5,str3);
			strcat(str5,str1);
			Search(0,str5);
			
			strcpy(str5,str3);
			strcat(str5,str2);
			Search(0,str5);
		
			strcpy(str5,str4);
			strcat(str5,str1);
			Search(0,str5);

			strcpy(str5,str4);
			strcat(str5,str2);
			Search(0,str5);
		}
		printf("%d\n",sum);
	}
	return  0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值