kickstart-F
A题
Anagrams字符串是指两个字符串中都出现相同的字母且这些字母出现的次数相同。
小数据完全可以暴力,遍历A的子串,遍历B的子串,通过bool f(i,j,k,l)计算A[i,j], B[k,l]是否符合要求,其中f函数要做的就是统计字母出现次数O(L)复杂度,同时4重循环找两个子串,总的复杂度是O(L^5).
下面优化一下,两个子串不等长肯定false,所以可以省略一个循环,bool f(i,j,k,k+(j-i)), 复杂度O(L^4).
能不能再优化呢?空间换时间好了,预处理B的子串,将字母统计量hash数组num[26]转换为string存到set中,时间复杂度O(L^2),为什么这么少呢,因为大神解法省去了计算统计量的循环,已知B[i..j]就可以直接计算B[i..j+1]了. 再遍历A的子串,统计它的字母统计量后看set中是否存在,存在cnt++即可. 最后的时间复杂度O(L^2)。
B题
一定要仔细读题,任意两个path的距离不等,观察样例特点,发现可以变化的只发生在距离为0的点,互相连接的点。其中因为要求最短距离,所以每次只统计与当前点邻接的最短距离,并记录端点。
1 #include <iostream> 2 #include<stdio.h> 3 #include <set> 4 #include <string> 5 using namespace std; 6 7 int main() 8 { 9 //freopen("/Users/zjg/CLionProjects/ac/B-large-practice.in","r",stdin); 10 //freopen("/Users/zjg/CLionProjects/ac/B-large-practice.out","w",stdout); 11 int T; 12 cin>>T; 13 for(int t=1;t<=T;t++) 14 { 15 int v,e; 16 set<int> zero; 17 int nn[v]; 18 int dis[v]; 19 fill(dis,dis+v,100001); 20 for(int i=0;i<e;i++) 21 { 22 int a,b,d; 23 cin>>a>>b>>d; 24 a--,b--; 25 if(d<dis[a]) 26 { 27 dis[a]=d; 28 nn[a]=b; 29 } 30 if(d<dis[b]) 31 { 32 dis[b]=d; 33 nn[b]=a; 34 } 35 if(d==0) 36 { 37 zero.insert(a); 38 zero.insert(b); 39 } 40 } 41 long long ans=1; 42 for(int i=0;i<v;i++) 43 { 44 if(nn[i]==-1)continue; 45 if(nn[nn[i]]==i) 46 { 47 ans<<=1; 48 nn[nn[i]]=-1; 49 nn[i]=-1; 50 } 51 else if(zero.count(nn[i])) 52 ans<<=1; 53 } 54 cout<<"Case #"<<t<<": "<<ans<<endl; 55 } 56 return 0; 57 }