【搜索】【字符串】【七中联考】

来源:互联网 发布:linux内核完全注释4.0 编辑:程序博客网 时间:2024/04/27 19:27

这里写图片描述

看到这个题不要方。
毕竟是第一道题,解法肯定不难。

思考:
首先看看一个序列 1 2 3 4 5 6… 这里我们只先猜想六位,
这个序列通过这种交换方式可以得到如何如何的规律~。

①必须换前缀。
②只能换偶数。

我们可以试着看看这个序列 1 2 3 4 5 6 可以得到什么样子的序列

*1 2 3 4 5 6
①换前两个 、、前四个 、、前六个
*2 1 3 4 5 6
*4 3 2 1 5 6
*6 5 4 3 2 1
再来一遍。
对于 2 1 3 4 5 6 换前四个 前6 个
*4 3 1 2 5 6 —->
*6 5 4 3 1 2 —->

对于 4 3 2 1 5 6 换前两个 前六个。

*3 4 2 1 5 6
*6 5 1 2 3 4

对于 6 5 4 3 2 1 换前两个 前 4 个
*5 6 4 3 2 1
*3 4 5 6 2 1

其实耐心写完是很容易发现规律的。。
然而并没有耐心。
可以注意到 对于最开始的1 2 3 4 5 6
相邻的两个数 (1 2) (3 4) (5 6 )
在之后的变换中都是连续的嘛,
姑且把 1 2 3 4 5 6
当做 a b c 每次可以换奇数个前缀和。
也就是说我们可以乱搞了。
换一换嘛。
a b c
我可以让a换到任意的位置。
b a c
或者
b c a
同理 b ,c 当然也可以换到任意一个位置。
a b c
a c b

c a b
a c b
好像全排列都可以= =

然后就出来了。
可以发现 (1,2)(3, 4) (5,6 ) 组成的全排列其实都可以得到。
而且 不一定是 (1,2) 也可以是 (2, 1)
因为
1 2 3 4 5 6
可以得到
2 1 3 4 5 6
和上面的结论是一样的。
(开始枚举的时候已经加粗了,说明 a b 或者 b a 可以插入序列中任何一个位置 。然后所以任何一个 序列的开头两个字母都可以插入序列中任何一个位置。)
从而得出任意成对的两个字符都可以插入序列中任何一个位置(当然是偶数的为)

所以对于string 1 以及 string 2
我们直接 枚举 string 2 的任意 两个配对的字符 在string1 中是否以配对的方式出现即可。

**re**do**po**tc
do**ct**po**er**
我们发现是可以两两配对的。
所以n*n枚举所有搭配。
然后 T*T/4 枚举所有配对方式。

如果是奇数位数
如果最后一位不相同。
不管怎么换都换不过来。。
特判即可。
1 2 3
3 2 1
是不是怎么搞最后一位都不能从 1 变成 3 嘛。
然后 时间刚好过。虽然数据很水。

#include<iostream>#include<cstdio>#include<queue>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int T,n,ans;string A[51];int len[51];int flag[51];bool cmp(string a,string b){    return a.length()<b.length();}bool work(int i,int j){    int used1[51],used2[51];    memset(used1,0,sizeof(used2));    memset(used2,0,sizeof(used2));    if((len[i]==len[j])&&(len[i]&1))        if(A[i][len[i]-1]!=A[j][len[j]-1])            return false;    char s1,s2,p1,p2;    for (int k=1;k<=len[i]/2;k++){        if(used1[2*(k-1)]==1) continue;        if(used1[2*(k-1)+1]==1) continue;        s1=A[i][2*(k-1)];        s2=A[i][2*(k-1)+1];        bool flag=false;        for (int p=1;p<=len[i]/2;p++){            p1=A[j][2*(p-1)];            p2=A[j][2*(p-1)+1];            if(used2[2*(p-1)]==1) continue;            if(used2[2*(p-1)+1]==1) continue;            if((s1==p1)&&(s2==p2)||((s1==p2)&&(s2==p1))){                used1[2*(k-1)]=used1[2*(k-1)+1]=used2[2*(p-1)]=used2[2*(p-1)+1]=1;                flag=true;                break;            }        }        if(flag==false){            return false;        }    }    return true;}int main(){    freopen("kahuucino.in","r",stdin);    //freopen("kahuucino.out","w",stdout);    cin>>T;    while(T--)    {        cin>>n;        ans=0;        memset(flag,0,sizeof(flag));        memset(len,0,sizeof(len));        for (int i=1;i<=n;i++) {            cin>>A[i];            len[i]=A[i].length();        }        for (int i=1;i<=n;i++){            for (int j=i+1;j<=n;j++){                if((flag[i]!=0)||(flag[j]!=0)) continue;                if(len[i]!=len[j]) continue;                else {                    bool pd=work(i,j);                    if(pd==true){                        flag[i]=1;                        flag[j]=1;                    }                }            }        }        for (int i=1;i<=n;i++)            if(flag[i]==0) ans++;        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击