HDU 4850 Wow! Such String!(构造推理)
2017-04-29 17:31
369 查看
题意:给定长度n 找到一个满足
1.长度为n
2.全为小写字母
3.长度>=4的子串只出现一次 的字符串 没有则输出Impossible
开始的时候就一直觉得这道题有规律 纠结于找不到这样串的临界点究竟是什么时候……
后来发现我真的想多了 = =就一直推下去 推不到就是Impossible
具体推理过程就是用vis四维数组标记连续的串是否出现:
vis[i][j][k][l] 就是表示’a’+i ‘a’+j ‘a’+k ‘a’+l 是否出现
然后前面26*4都用相同字母aaaabbbbcccc……zzzz这样填充
之后一个字母一个字母推
每次用 最大的字母 且 加上该字母后连续串在vis数组出现过 的填充
填充完在vis数组中将该字母加上之前三个字母的连续串在vis数组中置1
用flag标记 当某个位置取得最小字母时都无法填充时 说明不可以组成这样的串
某一段字母样例为:
aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz
yzzyyzyzyyyxzzzxzzyxzyzxzyyxyzzxyzyxyyzxyyxxzzxxzyxxyzxx
首先,如果反向推也是可行的,先从’z’~’a’填充,然后填充最小的字母zzzz…aaaabaab…
但是,如果’a’~’z’填充,然后每次选择最小的字母填充是不可行的,为什么呢?
先看一下如果用这样的想法最多的字符串:
可以明显看出,’a’过多的占用位置导致每4个位置的最后一个位置没有办法放下别的字母,如果需要继续放,必须改变第三个字母的再继续放入,想想就很麻烦
使用’z’~’a’的顺序用最大字母填充后面的位置能够改善这样的情况。
但是到底为什么这样可以出结果还是不知道啊
唉
1.长度为n
2.全为小写字母
3.长度>=4的子串只出现一次 的字符串 没有则输出Impossible
开始的时候就一直觉得这道题有规律 纠结于找不到这样串的临界点究竟是什么时候……
后来发现我真的想多了 = =就一直推下去 推不到就是Impossible
具体推理过程就是用vis四维数组标记连续的串是否出现:
vis[i][j][k][l] 就是表示’a’+i ‘a’+j ‘a’+k ‘a’+l 是否出现
然后前面26*4都用相同字母aaaabbbbcccc……zzzz这样填充
之后一个字母一个字母推
每次用 最大的字母 且 加上该字母后连续串在vis数组出现过 的填充
填充完在vis数组中将该字母加上之前三个字母的连续串在vis数组中置1
用flag标记 当某个位置取得最小字母时都无法填充时 说明不可以组成这样的串
某一段字母样例为:
aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz
yzzyyzyzyyyxzzzxzzyxzyzxzyyxyzzxyzyxyyzxyyxxzzxxzyxxyzxx
首先,如果反向推也是可行的,先从’z’~’a’填充,然后填充最小的字母zzzz…aaaabaab…
但是,如果’a’~’z’填充,然后每次选择最小的字母填充是不可行的,为什么呢?
先看一下如果用这样的想法最多的字符串:
可以明显看出,’a’过多的占用位置导致每4个位置的最后一个位置没有办法放下别的字母,如果需要继续放,必须改变第三个字母的再继续放入,想想就很麻烦
使用’z’~’a’的顺序用最大字母填充后面的位置能够改善这样的情况。
但是到底为什么这样可以出结果还是不知道啊
唉
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int N = 26*26*26*26+10; const int N1 = 26*4; int vis[30][30][30][30]; char s ; int main() { int n; while(~scanf("%d",&n)) { memset(vis,0,sizeof(vis)); memset(s,0,sizeof(s)); int cnt=0; char c='a'; int temp=n>N1?N1:n; for(int i=0; i<temp; i++) { if(cnt>=4) { cnt=0; c++; } s[i]=c; cnt++; } int flag=0; if(n>N1) { for(int i=3; i<N1; i++) { vis[s[i-3]-'a'][s[i-2]-'a'][s[i-1]-'a'][s[i]-'a']=1; } for(int i=N1; i<n; i++) { flag=0; for(char j='z'; j>='a'; j--) { if(vis[s[i-3]-'a'][s[i-2]-'a'][s[i-1]-'a'][j-'a']==0) { flag=1; s[i]=j; vis[s[i-3]-'a'][s[i-2]-'a'][s[i-1]-'a'][j-'a']=1; break; } } if(!flag) { break; } } } else flag=1; if(!flag) puts("Impossible"); else printf("%s\n",s); } }
相关文章推荐
- hdu 4850 Wow! Such String! 构造 或 欧拉路径并改写成非递归版本
- HDU_4850_Wow! Such String!(构造)
- HDU-4850 Wow! Such String! (构造)
- hdu 4850 Wow! Such String! 构造 欧拉回路
- 构造字符串 之 hdu 4850 Wow! Such String!
- HDU-4850 Wow! Such String! (构造)
- HDU - 4850 Wow! Such String! 构造(字符串上的欧拉回路)
- hdu 4850 Wow! Such String! 构造 欧拉回路
- 构造字符串 之 hdu 4850 Wow! Such String!
- hdu 4850 Wow! Such String!(欧拉回路)
- HDU 4850 2014西安邀请赛 D题 Wow! Such String!
- HDU 4850 Wow! Such String!(欧拉道路)
- HDU 4850 Wow! Such String! 欧拉路径
- 【HDU】4850 Wow! Such String! 提出猜想题
- HDU 4850 Wow! Such String!
- hdu 4850 Wow! Such String!(字符串处理,yy)
- HDU 4850 2014西安邀请赛 D题 Wow! Such String!
- 【HDU】4850 Wow! Such String! 提出猜想题 欧拉道路
- HDU 4850 Wow! Such String! 欧拉回路
- hdu 4850 Wow! Such String! 2014西安全国邀请赛