题目链接:http://acm.timus.ru/problem.aspx?space=1&num=2037
题意:给一个n,对于每个i∈[1,n],都给出一个字符串si,si仅由字符'a'和'b'组成,长度为n且含有i个不同的回文子串,若无输出NO。
思路:没找到什么好思路,只能打表找规律。然后我们可以发现,n<=7,只有i等于n,si才存在;n等于8时,i从[7-8]存在si;n>=9,i从[8,n]存在。
对于n>=9,打表找规律。会发现是由三部分组成:
①i==n,全部构造成‘a’即可。
②从i=n-1开始记做第一个,此时应构造成左边两个'a',中间是bbab,右边全部填充'a'
随着i每次减少,左边的a多一个,右边的a少一个,直到左边的a的个数超过右边的a的个数(可以相等)。
③i==8时记做第一个,此时一个循环节为bbab+2个'a',从右往左放,直至长度为n为止。随着i增大,'a'的个数加1。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
int n;
//int temp[20];
//bool check(int st,int len)
//{
// int p = st;
// int q = st+len-1;
// while( p < q )
// {
// if ( temp[p] != temp[q] ) return false;
// p++ , q--;
// }
// return true;
//}
//string f( int st , int len )
//{
// string ans = "";
// rep(i,1,len)
// {
// ans = ans + (char)(temp[st]+'0');
// st++;
// }
// return ans;
//}
//void init()
//{
// bool flag[20];
// Clean(flag,false);
// Clean(temp,0);
// map<string,int> a;
// rep(i,0,(1<<n )- 1)
// {
if ( i == (1<<n )- 1 )
puts("");
// int ttt = i;
// int L = 0;
// while(ttt)
// {
// temp[++L] = ttt % 2;
// ttt >>= 1;
// }
// a.clear();
// int x = 0;
// rep(len,1,n)
// rep(i,1,n-len+1)
// if ( check(i,len) )
// {
// string num = f(i,len);
// if ( a[num] == 0 ) x++,a[num] = 1;
// }
// if ( x < n && !flag[x] )
// {
// flag[x] = true;
// printf("%d:\n",x);
// rep(i,1,n) cout<<temp[i];
// puts("");
// }
printf("%d:\n",x);
rep(i,1,n) cout<<temp[i];
puts("");
// }
// puts("");
//}
void puta(int k)
{
rep(i,1,k) putchar('a');
}
void putb(int k)
{
rep(i,1,k) putchar('b');
}
int main()
{
// while( cin>>n )
// {
// if ( n == 0 ) break;
// init();
// }
//注释部分为粗糙的打表
int n;
cin>>n;
rep(i,1,n)
{
printf("%d : ",i);
if ( i <= 6 && i != n )
puts("NO");
else if ( i == n )
{
puta(n);
puts("");
}
else if ( i == 7 )
{
if ( n == 8 )
puts("aabbabaa");
else puts("NO");
}
else //上面是特殊情况。
{
int l = n + 1 - i; //第二种情况
int r = n - 4 - l;
if ( l <= r )
{
puta(l);
printf("bbab");
puta(r);
puts("");
}
else //第三种情况
{
int z = i - 8 + 2; //后面+'a'的个数
int len = 4 + z; //一个循环的长度
int ret = n % len; //最左边不完整循环的长度
if ( ret == z + 4 )
printf("bbab");
else if ( ret == z + 3 )
printf("bab");
else if ( ret == z + 2 )
printf("ab");
else if ( ret == z + 1 )
printf("b");
if (ret) puta( min( z,ret) ); //输出不完整循环部分
len = n/len;
rep(i,1,len) //输出完整循环部分
{
printf("bbab");
puta(z);
}
puts("");
}
}
}
return 0;
}