E. Mo的遊戲
單測試點時限: 1.0 秒
內存限制: 512 MB
Mo翻書看到一種新的連連看遊戲:對於一個字符串來說,只有當兩個字符相同時候纔可以進行相連,得分爲字符串的長度減去兩個相連字符的距離(如果整個字符串中某一種字符個數爲1,那麼不能相連故得分爲0)。Mo現在在玩這個遊戲,但是Mo不知道該選擇哪一種字符進行相連,所以請你列出每種字符相連可以獲得的最大分數,以此來讓Mo進行參考。
輸入
一個字符串s (0<strlen(s)<106, s中只包含大小寫字符)。
輸出
針對s中出現過的字符,每行輸出一個整數表示用當前字符進行相連可以獲得的最大分數, 按照a−z,A−Z的順序。具體格式參見樣例。
樣例
input
Aabcaabcb
output
a:8
b:7
c:5
A:0
思路:通過讀題,不難得出,字符的得分 = 字符串的長度 — 同樣的字符之間的距離;
只要求出每種同樣字符之間最小的距離就行了:
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
struct su{
char st;
int v;
};
int main(){
string s;
cin>>s;
map<char,int> last; //上一個同樣字符的位置
map<char,int> m; //統計字符個數
map<char,int> ans; //結果
vector<su> v;
int n=s.length();
for(int i=0;i<n;i++){
m[s[i]]++; //計數
if(m[s[i]]<2){
last[s[i]]=i; //每種符號的第一次出現
}
else if(m[s[i]]==2){ //第二次出現,這時候纔可以"對消"
ans[s[i]]=i-last[s[i]]; //ans[]:記錄第一個可能爲答案的數值
last[s[i]]=i; //更新位置
}
else {
ans[s[i]]=min(ans[s[i]],i-last[s[i]]); //ans[]:記錄兩個相鄰同樣字符距離最小值
last[s[i]]=i;
}
}
map<char,int>::iterator it=m.begin();
su r;
for(;it!=m.end();it++){
r.st=it->first;
if(ans[r.st])
r.v=n-ans[r.st];
else
r.v=0;
v.push_back(r);
}
for(int i=0;i<v.size();i++){ //不想排序了,直接輸出QAQ
if(v[i].st>='a'&&v[i].st<='z')
cout<<v[i].st<<":"<<v[i].v<<endl;
}
for(int i=0;i<v.size();i++){
if(v[i].st>='A'&&v[i].st<='Z')
cout<<v[i].st<<":"<<v[i].v<<endl;
}
return 0;
}