题意:如果两个单词首尾字母相同,仅中间字母的顺序被打乱,这两个单词被视作相等的。给定一个dictionary (a list of words),一个sentence,问有多少个dictionary中的单词出现在sentence里面。
赛后发现小数据竟然可以暴力水过o(╯□╰)o。对于每一个单词,遍历sentence中相同长度的子串,如果首尾子母相同,就把中间部分sort之后,判断两个单词是否相等。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
其实大数据也木有完全解决,大概跑9-10min能跑完。
在给定一个Word with length l遍历sentence时候,S[i,i+l]与S[i+1,i+l+1]中间的l-2的letter都是重合的,所以不需要每次都重新compare S[i,i+l]与Word是否相同。因为只有26个字母,可以通过维护一个frequency array实现,e.g, freq_array[0,1,2,3,..26],freq_array[0]表示sub string S[i,i+l]中a出现的次数。Then from S[i,i+l] to S[i+1,i+l+1],只需要改变S[i]和S[i+l+1]对应的freq_array的值即可。
large input无法用O(LN)暴力枚举。但是隐含条件说dictionary中Word length之和M<=1e5。M限制了word length的种类个数。word length 种类假设有X种,那么最多的情况是每个Word的length都只有一个,即1+2+...+X<=M,因此X=447.21,scale小了很多。
因此可以将相同length的Word的frequency array存在一个multiset里面(和set相比multiset允许重复的元素),对于每个出现过的length,遍历subsrting,在multiset中查找对应的frequency array是否有word出现过。因为每个Word只统计是否出现,查找到的Word需要从set中删除。为了保证首位letter相同,frequency array再加两项表示首尾字母即可。
因为multiset不能存数组(需要copy等操作),所以先转换成了array存进去,c++11中的array可以直接存在set里面。以后再看看。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include