5.5.1 picture
nocow上有个非常巧妙地办法,横轴和纵轴扫描一遍,单独计算。
2种计算方法相同,比如算横轴
初始化一个数组h[]=0,按高度将横边排序,每投影下一条边,对每个点i 若是下边 h[i]+1,若是上边 h[i]-1,若h[i]被计算后变成了1则周长+1;
并且保证相同高度的横边 上边排在下边后,因为重复部分是不算周长的。
这里统计时要注意,末端点不能投影 因为‘. . .’表示的长度为2。
5.5.2 hinden password
做这题之前我还很囧很囧地以为memcmp比较直接比较内存块 是常数时间的,就像你自己的身体受到再复杂的刺激,也能马上有反应一样.而事实上,没有O(1)的比较算法 >。<|||,于是第一次用朴素的比较超时了。
其实这题要用 最小表示 的思想(不会后缀数组- -),引入一个点p,表示从p开始的循环字符串是最小的。然后安排2个指针,u=0,v=1,问题转化为 怎样移动他们以保证u<=p。(详见wc周源的‘最小表示法’)
void compare()
{
u=0,v=1,k=0;
while(v<n)
{
while(str[u+k]==str[v+k]&&k<n)k++;
if(str[u+k]>str[v+k])
{
u+=k+1;
k=0;
if(u==v)v++;
}
else
{
v=v+k+1;
if(v==u)v++;
k=0;
}
}
}
5.5.3 twofive
头大 看了题解并纠结一晚的题t_t.
本质就是不断找出前面的字符,缩小集合范围 最后确定整体字符串。有个关键的地方要考虑:如何知道有特定前缀的字符串共有多少种,以及如何保证合法。
囧 还是dp。按字母表的次序放入矩阵,用一个5维数组f[a][b][c][d][e]表示方案数,每次在f地一个维度中放入一个字母,但要保证它的上和左已经放过 举例来说 在第2维放的时候 要保证b<a, 由于是按字典序放的,当前字母的左和上的字母肯定比它小,这就保证了行列递增。
转移方程
f[a][b][c][d][e]+=f[a+1][b][c][d][e]
+=f[a][b+1][c][d][e]
.
.
.
(当然 要先判断合法性 即 if(a>b),if(b>c)....)
charpter 5 完成了 压力巨大 好累啊..... 第6做不动
最近几次小型比赛只能ac几道水题,事后反省发现很多其实都可以拿下的,usaco做太快了也不好,之前学过的东西没有加强,往后做也就失去意义了...... charpter6先放下 寒假干掉。