[COCI2010-2011#2] IGRA 题解
wzb13958817049 · · 题解
思路
贪心,因为 Mirko 每次只会拿最后一个单词,所以 Slavko 要想赢就要拿剩下单词中字典序最小的且排在越后面越好。这样我们可以很好的想到暴力,去拿
#include<bits/stdc++.h>
using namespace std;
long long n,j;
string a,ans1,ans2;//ans1表示Slavko拿到的最美丽单词
//ans2表示Mirko拿到的单词
vector<long long> mp[27];
bool vis[200005];//该位置是否被访问过
int main(){
cin>>n>>a;
for(int i=0;i<a.size();i++) mp[a[i]-'a'+1].push_back(i);//把字母保存到vector中
j=n-1;//最后一个字母的下标
while(ans1.size()+ans2.size()<a.size()){
while(vis[j]==1 && j!=0) j--;//Mirko先手
ans2+=a[j];vis[j]=1;//记录下标为j的字母已经被拿走
bool falg=0;
for(int i=1;i<=26;i++){//从小到大遍历,找到第一个有的字母(最小)
for(int k=mp[i].size()-1;k>=0;k--){//从后往前遍历因为越后面越好
if(vis[mp[i][k]]==0){//如果没被拿走
ans1+='a'+i-1;
vis[mp[i][k]]=1;//标记
mp[i].erase(mp[i].begin()+k);//删除
falg=1;
break;
}
}
if(falg==1) break;
}
}
if(ans1<ans2) cout<<"DA";
else cout<<"NE";
cout<<"\n"<<ans1;//输出答案
return 0;
}
但是因为代码太朴素,还是会
ACcode
#include<bits/stdc++.h>
using namespace std;
long long n,j,kkk;
string a,ans1,ans2;
vector<long long> mp[27];
bool vis[200005];
int main(){
cin>>n>>a;
for(int i=0;i<a.size();i++) mp[a[i]-'a'+1].push_back(i);
j=n-1;
while(ans1.size()+ans2.size()<a.size()){
while(vis[j]==1 && j!=0) j--;
ans2+=a[j];vis[j]=1;
bool falg=0;
for(int i=kkk;i<=26;i++){
for(int k=mp[i].size()-1;k>=0;k--){
if(vis[mp[i][k]]==0){
ans1+='a'+i-1;
vis[mp[i][k]]=1;
mp[i].erase(mp[i].begin()+k);
kkk=i;
falg=1;
break;
}
}
if(falg==1) break;
}
}
if(ans1<ans2) cout<<"DA";
else cout<<"NE";
cout<<"\n"<<ans1;
return 0;
}