蚂蚁2022.9.15笔试题解
第一题挺简单的,略过。
第二题的话,建图跑一个dfs就好,对于每个点,如果其子节点的标记值大于它,则把差值累加到答案上,输出即可。(这里有个坑点,当出现任意一个父节点的标记值小于其子节点的标记值时,很明显是无法实现题目的情况的,也就是没有答案,这里应该输出-1,但是出题人没写,应该是题面漏放了)
第三题的话,由于我们只需要关心字母出现的奇偶性,那么我们可以对任意一个字符串,都用一个26位的数字来表示其26个字母的奇偶性状态。
我们先对整个字符串做个前缀和,那就得到了200001个状态,使用map记录每个状态出现了多少次,然后用auto for去遍历map里的每个状态,再for一遍26位字母,改变其奇偶性,也就是说把
M[now]*M[now^(1<<i)] (i取0到25)累加到ans上,最后输出ans/2即可
补贴个第三题的代码:
#include<bits/stdc++.h> #define ll long long using namespace std; ll ans = 0; map<int,int>M; char s[200007]; int main(){ scanf("%s",s); int len = strlen(s); int now = 0;//初始状态为0,每个字母都出现了0(偶数)次 M[0] = 1; for(int i = 0; i < len; i++){ int temp = s[i] - 'a'; now ^= (1 << temp); if(M.find(now) == M.end()) M[now] = 1; else M[now]++; } for(auto x:M){ int now = x.first; for(int i = 0; i < 26; i++){ ans += M[now] * (ll)M[now ^ (1 << i)]; } } printf("%lld\n",ans/2); }