农夫约翰的农场布局十分奇特,一条大型的环形道路将奶牛吃草的田地围了起来。

每天早晨,奶牛们穿过这条道路,进入到田地吃草;每天晚上,奶牛们穿过这条道路,离开田地,返回牛棚休息。

众所周知,奶牛是有习性的动物,每头奶牛每天通过道路的方式都相同。

每头奶牛每天固定地从道路的某一位置进入田地,从道路的另一不同位置离开田地。

所有奶牛的所有进出位置之间互不相同。

约翰共有 牛为什么过马路 II(寒假每日一题 26)_ios 头奶牛,依次命名为 牛为什么过马路 II(寒假每日一题 26)_#include_02

因此,道路上共有 牛为什么过马路 II(寒假每日一题 26)_#include_03 个不同的进出位置。

约翰沿着环形道路按顺时针方向扫描了每个位置,并记录了每个位置处经过的奶牛的名字,最终形成了一个包含 牛为什么过马路 II(寒假每日一题 26)_#include_03 个字母的序列,牛为什么过马路 II(寒假每日一题 26)_#include_02 中的每个字母恰好出现两次。

他并没有记录哪些位置是入口,哪些位置是出口。

看着地图上记录的这些位置,约翰想要知道一天当中,有多少对奶牛之间的从入口穿过田地到达出口的路径可能会存在交叉。

如果奶牛 牛为什么过马路 II(寒假每日一题 26)_算法_06 从入口穿过田地到达出口的路径必须穿过奶牛 牛为什么过马路 II(寒假每日一题 26)_枚举_07 从入口穿过田地到达出口的路径,那么称这对牛 牛为什么过马路 II(寒假每日一题 26)_i++_08 是“交叉”对。

请帮助约翰计算“交叉”对(不考虑顺序,即 牛为什么过马路 II(寒假每日一题 26)_i++_08牛为什么过马路 II(寒假每日一题 26)_#include_10 视为同一对 )的总数。

输入格式
共一行,包含一个长度为 牛为什么过马路 II(寒假每日一题 26)_#include_03 的只包含大写字母的字符串,其中每个字母恰好出现两次。

输出格式
输出交叉对的总数。

输入样例:

ABCCABDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ

输出样例:

1

样例解释
在此样例中,只有 牛为什么过马路 II(寒假每日一题 26)_算法_06牛为什么过马路 II(寒假每日一题 26)_枚举_07 一对交叉对。


​解法一​

#include<iostream>

using namespace std;

char str[100];
int pos[100];

int solve(int a, int b){

int q[30] = {0};
for(int i = a; i <= b; i++) q[str[i] - 'A']++;

int res = 0;
for(int i = 0; i < 26; i++)
if(q[i] == 1) res++;

return res;
}

int main(){

scanf("%s", str + 1);

int res = 0;
for(int i = 1; i <= 56; i++){

int x = str[i] - 'A';

if(!pos[x]) pos[x] = i;
else res += solve(pos[x] + 1, i - 1);
}

cout << res / 2 << endl;

return 0;
}

​解法二​

#include<iostream>
#include<vector>

using namespace std;

vector<int> p[26];

int main(){

string s;
cin >> s;

for(int i = 0; i < s.size(); i++)
p[s[i]-'A'].push_back(i);

int res = 0;
for(int i = 0; i < 26; i++){
for(int j = i + 1; j < 26; j++){

int cnt = 0;
for(auto y: p[j])
if(p[i][0] < y && y < p[i][1])
cnt++;

if(cnt == 1) res++;
}
}

cout << res << endl;

return 0;
}