CF1624D【黄】-思维题
题目: https://www.luogu.com.cn/problem/solution/CF1624D
这道题很简单,但是启发我把这一类题都起名为思维题,贪心题大部分都是思维题,但还有很多不属于贪心题的思维题,总之思维题就是考察思维能力,和算法无关,通常能做出来的都能轻松做出,做不出来的想破头也想不出来,这道题属于前者。
Code
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <cmath>
#define int long long
using namespace std;
int T,n,k,b[30],ans,duizi,dan;
char x;
signed main()
{
cin>>T;
while(T--)
{
for(int i=1;i<=26;i++)b[i]=0;
duizi=0;dan=0;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>x;
b[x-'a'+1]++;
//分成了u个成对的字母v个单独的字母,我们手头有k个颜色,单独的字母
//如果最长和最短差距>=3,最长就可以拿出一对给最短,缩小差距,因此最长和最短差距<=2;我们应该有限分配对子,知道某些人只比另一些人多一对
//然后分配单独的字母,优先分配给少了一对的人,再多就不分配了
}
for(int i=1;i<=26;i++)
{
if(b[i]%2==0)
{
duizi+=b[i]/2;
}
else
{
dan++;
duizi+=(b[i]-1)/2;
}
}
if(duizi%k==0)
{
if(dan<k)ans=duizi/k*2;
else ans=duizi/k*2+1;
}
else
{
if(dan+duizi%k*2>=k)ans=duizi/k*2+1;
else ans=duizi/k*2;
}
cout<<ans<<endl;
}
return 0;
}