Gym - 101972F I'm Bored! 模擬暴力
Being a judge is not always an interesting job! For example, it is very boring to wait for the first submission in the contest. So, judges used to entertain themselves using the "I'm Bored" tab in the PC2 software. In this tab, a button is shown and you need to click it (if you can!).
Since Alaa has been a judge in many contests, the "I'm Bored" tab is also boring to her, so, she decided to play a new game in today's contest. Alaa brings with her a huge bag full of lowercase English letters, and she starts playing with them. Alaa goal is to build a list of palindrome strings of the same length such that each string does not contain the same character more than two times.
After 3 minutes of playing, Alaa wondered what is the longest string's length that she can build? And what is the maximum number of strings the list can contain? When Alaa brings her notebook to calculate the answers, she starts receiving dozens of submissions. So, she gives you her bag and asks you to find the answers for her. Can you?
Input
The first line contains an integer T (1 ≤ T ≤ 104) specifying the number of test cases.
Each test cases consists of a line containing 26 integers f1, ..., f26 (0 ≤ fi ≤ 109), in which fi is how many letters i Alaa has. The letters are numbered from 1 to 26starting from 'a'.
Output
For each test case, print a single line containing two integers x and y, in which xis the length of the strings in the group and y is the size of the group.
Example
Input
2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Output
4 1 4 2
Note
A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as "madam" or "racecar".
題意:給定一個26個字母的個數,要求能組成最長迴文串的長度,與最長長度的個數,迴文串中每種字母最多選兩個
題解:先判斷最多的數量,然後每次模擬著寫就行了,最多進行也超不過26次,詳見程式碼解釋
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+100;
typedef long long ll;
ll num[27];
int n;
bool cmp(ll x,ll y)
{
return x>y;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=1;i<=26;i++)
scanf("%lld",&num[i]);
sort(num+1,num+1+26,cmp);
ll cnt=0,pos=0; // cnt 選出的最少的字元個數 pos 能選多少個
ll ans=0,res=0; // ans 記錄最多那多少個 res 可以組成的數量
for(int i=1;i<=26;i++)
{
if(num[i]<=1)
{
ans+=num[i];
pos=i;
cnt=num[i];
break;
}
ans+=2;
pos=i;
cnt=2;
}
if(cnt==0) pos--,cnt=min((ll)2,num[pos]);
if(ans==0)
{
printf("0 0\n");
continue;
}
while(1)
{
if(num[pos]<cnt)
{
break;
}
ll tmp=num[pos]/cnt; //tmp 還能拿出多少個
if(pos>1) // 如果前面有,前面肯定至少拿2個
{
if(num[pos-1]<2) break;
tmp=min(tmp,num[pos-1]/2);
}
for(int i=1;i<pos;i++) // 更新
num[i]-=tmp*2;
num[pos]-=tmp*cnt;
res+=tmp;
sort(num+1,num+1+26,cmp);
}
printf("%lld %lld\n",ans,res);
}
return 0;
}