阿里云编程大赛初赛第一场(3/4)
A.树木规划
直接按顺序删即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { public: /** * @param trees: the positions of trees. * @param d: the minimum beautiful interval. * @return: the minimum number of trees to remove to make trees beautiful. */ int treePlanning(vector<int> &trees, int d) { // write your code here. int pre=trees[0]; int ans=0; for (int i=1;i<trees.size();i++) { if (trees[i]-pre>=d) { pre=trees[i]; } else { ans++; } } return ans; } };
B.正三角形拼接
分类讨论,讨论方法在代码里。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { public: /** * @param lengths: the lengths of sticks at the beginning. * @return: return the minimum number of cuts. */ int makeEquilateralTriangle(vector<int> &lengths) { // write your code here. int ans=3; //分类讨论 //第一类,已经有三根一样长的木棍,输出0 //第二类,有两根长度一样的木棍,看看最长的木棍长度是否比这个长度大,如果是返回1 //第三类,木棍长度互不相同,看是否有一根木棍的长度是当前木棍长度的两倍,如果是返回1 //如果不是,看最长的一根木棍是否比这个两倍长,如果是返回2 // map<int,int> p; sort(lengths.begin(),lengths.end()); for (int i=0;i<lengths.size();i++) p[lengths[i]]++; for (auto it=p.begin();it!=p.end();it++) { if (p[it->first*2]) { ans=min(ans,1); } if (it->second>=3) { ans=min(ans,0); } if (it->second>=2&&lengths.back()>it->first) { ans=min(ans,1); } if (lengths.back()>it->first*2) { ans=min(ans,2); } } return ans; } };
D.对称前后缀
枚举所有子串,对于每个子串,二分最长对称前后缀,check这个过程可以用字符串哈希水过去,总体时间复杂度O(n*n*logn)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { public: /** * @param s: a string. * @return: return the values of all the intervals. */ long long suffixQuery(string &s) { // write your code here int n=s.length(); long long f[3500]={0}; long long p[3500]={0}; long long f1[3500]={0}; long long p1[3500]={0}; f[0]=1; p[0]=1; f1[n+1]=1; p1[n+1]=1; for (int i=1;i<=n;i++) { f[i]=f[i-1]*13331+(s[i-1]+1); p[i]=p[i-1]*13331; } for (int i=n;i>=1;i--) { f1[i]=f1[i+1]*13331+(s[i-1]+1); p1[i]=p1[i+1]*13331; } long long ans=0; for (int i=1;i<=n;i++) { for (int j=i;j<=n;j++) { if (i==j) { ans++; continue; } int l=1,r=j-i+1; int u=0; while (l<=r) { int mid=(l+r)>>1;//二分的最长对称前后缀 if (f[i+mid-1]-f[i-1]*p[mid]==f1[j-mid+1]-f1[j+1]*p[mid]) { u=mid; l=mid+1; } else { r=mid-1; } } if (!u) continue; //printf("%d<br>",u); ans+=u; } } return ans; } };