这题大家可能一上来没有思路,但仔细分析后的确只是一道橙题难度。
我的大体思路就是:在一开始,用一个数组存储这个字符串中每个字母出现的次数。
for(int i=0;i<n;i++)
a[s[i]-'A']++; //相当于用字符做下标。
然后进入一个循环,遍历整个字符串。
在每次循环的开始,将遍历到的字母对应的数量减 (1)。
--a[s[i]-'A'];
如果这个字母是首次出现,那么就需要一个士兵去看守,所以士兵数量就减 (1)。
if(book[s[i]-'A']==0) //用一个数组记录是否第一次出现。
{
--k; //如果是的话,士兵数减一。
book[s[i]-'A']=1;
}
接下来进行判断。如果士兵不够用了(即士兵数量小于 (0)),就输出 “ YES ”,结束程序。
if(k<0) //如果士兵没了。
{
cout<<"YES";
return 0;
}
否则,判断这个字母是否是最后一次出现。如果是,就有一个士兵可以干其他事了。
if(a[s[i]-'A']==0) //如果此字母数量等于 0 了,就说明这是最后一次出现。
++k;
如果一整个循环跑完,了程序还在运行,那么士兵就够用,输出“ NO ”。
泥萌最喜欢的完整 AC 代码:
#include<bits/stdc++.h>
using namespace std;
int n,k,a[26];
bool book[26];
string s;
int main()
{
cin>>n>>k>>s;
if(k==26) //这是一个特判,如果有 26 个士兵,就肯定够用。
{
cout<<"NO";
return 0;
}
for(int i=0;i<n;i++)
a[s[i]-'A']++;
for(int i=0;i<n;i++)
{
--a[s[i]-'A'];
if(book[s[i]-'A']==0)
{
--k;
book[s[i]-'A']=1;
}
if(k<0)
{
cout<<"YES";
return 0;
}
if(a[s[i]-'A']==0)
++k;
}
cout<<"NO";
return 0;
}
逃(