题目链接:B.SGA President
我的解法:
在打比赛时,自认为没问题,但一直wa,wa了四五遍,但还是没有发现问题,虽然办法比较蠢,但好歹能解出答案(测试好几个数据没有问题)…,求大佬指点。
#include <iostream>
#include <cstring>
#include <algorithm>
const int N = 100000 + 5;
using namespace std;
int n;
string s[N];
int main()
{
cin >> n;
for(int i = 0; i < n; ++i) cin >> s[i];
if(n <= 0) {
cout << "0" << endl;
return 0;
}
int ans = 0; // 记录相同名字的个数
int a[35], b[35], cnt = 0;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b)); // 清零
sort(s, s + n); // 从小到达进行排序
a[s[0][0] - 'A']++;
for(int i = 1; i < n; ++i) {
a[s[i][0] - 'A']++;
if(s[i] == s[i - 1]) b[s[i - 1][0] - 'A']++; // 分组别
}
long long sum = 0;
for(int i = 0; i <= 25; ++i) {
if(a[i] >= 2) {
sum += (long long)a[i] * (a[i] - 1);
sum -= (long long)b[i] * (b[i] + 1);
}
}
cout << sum << endl;
return 0;
}
正解:
其实和我差不多,就是用了一个map,统计相同字符串的个数,再用一个数组来统计相同字母开头的遍数,for()跑一边就行。
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
typedef long long ll;
const int N = 100000 + 5;
int n;
string s[N];
map <string,int> mp; // 做一个映射, 统计相同字符串出现的次数
ll nm[30]; // 统计首字母出现的个数
int main()
{
cin >> n;
for(int i = 1; i <= n; ++i) {
cin >> s[i];
mp[s[i]]++;
nm[s[i][0] - 'A']++;
}
ll ans = 0;
for(int i = 1; i <= n; ++i) {
ans += nm[s[i][0] - 'A'] - mp[s[i]];
}
// 组合
cout << ans << endl;
return 0;
}
求指正~~