poj 3007 Organize Your Train part II

本文探讨了一种通过翻转字符串来计算不同排列数量的方法。首先介绍了算法的基本思路,然后详细解析了代码实现过程,包括如何使用哈希函数标记翻转后的字符串,以及通过循环和交换字符来生成所有可能的翻转情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给你一个字符串,通过翻转能得到多少种不同的字符串。

思路:其实这题刚一读完题感觉很繁琐,但是仔细研究一下题目中给出的例子会发现也不是那么复杂,或许是看了ZJH的博客后,突然想通了,感觉复杂例子,也可以将它分类简单化。

例如给你字符串:abcdef,第一种情况是串本身,第二种情况是bacdef,第三种情况是:bafedc,第四种情况是:abfedc,然后分别对这四种情况进行翻转,用hash函数标记。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string>
#define maxm 10005
#define maxn 100
using namespace std ;

struct node
{
    char st[maxn] ;
    int mark ;
}p[maxm] ;

int sum ;
char str_a[maxn] , str_b[maxn] ;

void find ( char str[] , int len )
{
    int s = 0 ;
    str[len]='\0' ;
    for ( int i = 0 ; i < len ; i++ )
    s += ( ( i + 1 ) * ( str[i] - 'a' )) ;
    while ( 1 )
    {
        if ( p[s%maxm].mark == 1 )
        {
            if ( strcmp ( p[s%maxm].st , str ) == 0 )
            break;
            s++ ;
        }
        else
        {
            sum++ ;
            strcpy ( p[s%maxm].st , str ) ;
            p[s%maxm].mark = 1 ;
            break;
        }
    }
}

int main()
{
    int cas , len , i , j , k ;
    char tem ;

    scanf ( "%d" , &cas ) ;
    getchar ();
    while ( cas-- )
    {
        memset( p , 0 , sizeof ( p ));
        sum = 0 ;
        scanf ( "%s" , str_a ) ;
        len = strlen ( str_a ) ;
        find ( str_a , len ) ;
        for ( i = 1 ; i < len ; i++ )
        {
            for ( k = 0 , j = i ; k < len ; k++ , j++ )
            str_b[k] = str_a[j%len] ;
            find ( str_b , len ) ;
            for ( k = 0 ; k < i / 2 ; k++ )//bacdef
            swap ( str_a[k] , str_a[i-k-1] ) ;
            find ( str_a , len );
            for ( k = 0 , j = i ; k < len ; k++ , j++ )
            str_b[k] = str_a[j%len] ;
            find ( str_b , len ) ;
            for ( k = i ; k < ( len + i ) / 2 ; k++ )//bafedc
            swap ( str_a[k] , str_a[len+i-k-1] ) ;
            find ( str_a , len ) ;
            for ( k = 0 , j = i ; k < len ; k++ , j++ )
            str_b[k] = str_a[j%len] ;
            find ( str_b , len );
            for ( k = 0 ; k < i / 2 ; k++ )//abfedc
            swap ( str_a[k] , str_a[i-k-1] ) ;
            find ( str_a , len ) ;
            for ( k = 0 , j = i ; k < len ; k++ , j++ )
            str_b[k] = str_a[j%len] ;
            find ( str_b , len ) ;
            for ( k = i ; k < ( len + i ) / 2 ; k++ )//abcdef
            swap ( str_a[k] , str_a[len+i-k-1] ) ;
        }
        printf ( "%d\n" , sum ) ;
    }
    return 0 ;
}

转载于:https://www.cnblogs.com/misty1/archive/2012/06/28/2567802.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值