1. 程式人生 > >HDU 5744 Keep On Movin (思維題,水題)

HDU 5744 Keep On Movin (思維題,水題)

amp tle 輸出 ngs pro ber end use view

Problem Description Professor Zhang has kinds of characters and the quantity of the i-th character is ai. Professor Zhang wants to use all the characters build several palindromic strings. He also wants to maximize the length of the shortest palindromic string.

For example, there are 4 kinds of characters denoted as ‘a‘, ‘b‘, ‘c‘, ‘d‘ and the quantity of each character is {2,3,2,2}
. Professor Zhang can build {"acdbbbdca"}, {"abbba", "cddc"}, {"aca", "bbb", "dcd"}, or {"acdbdca", "bb"}. The first is the optimal solution where the length of the shortest palindromic string is 9.

Note that a string is called palindromic if it can be read the same way in either direction.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1n105) -- the number of kinds of characters. The second line contains n integers a1,a2,...,an (0ai104). Output For each test case, output an integer denoting the answer. Sample
Sample Input

4
4
1 1 2 4
3
2 2 2
5
1 1 1 1 1
5
1 1 2 2 3
 

Sample Output

3
6
1
3

題意:

  開始輸入T,有T組測試樣例,每組測試樣例給定n個數,代表n個字符的個數,每個數代表的字符是唯一確定的,將這些字符組成若幹個回文串(可以一個,也可以多個),找出所有組合方式中最短 回文串 的最長長度。

  比如第一組樣例 一共有4個字符,假定為ABCD,其中A有1個,B有1個,C有2個,D有4個。組成的回文有{(CAC)(DDBDD)}或者{(A)(B)(CC)(DDDD)}等多種方式,其中第一種情況中,最短的長度為3,所以答案為3。再看題意中給出的樣例,一共有4個字符,假定為ABCD,其中A有2個,B有3個,C有2個,D有2個。組成的回文有{"acdbbbdca"}, {"abbba", "cddc"}, {"aca", "bbb", "dcd"}, {"acdbdca", "bb"}。在第一種情況中,最短的長度為9,所以輸出為9。

思路:

  如果是單個的,想構成較長的回文,至少有一對字符來和他組成,組成為ABA。

  所以,統計所有的字符中奇數的1的個數和偶數2的對數,比如一個字符有5個,則表示為2對偶數,1個奇數。

  最後判斷奇數和偶數的數量關系,如果奇數為0,偶數不為0,輸出偶數*2(因為偶數是對數,不是個數),如果奇數偶數都不為0,將偶數平均分配到奇數中,表示一個奇數對應這n對偶數,輸出(偶數對數/奇數個數)*2+1。

代碼:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int a[101000];
int main()
{
    int n;
    int m;
    cin>>m;
    for(int j=0; j<m; j++)
    {
        cin>>n;
        for(int i=0; i<n; i++)
            cin>>a[i];
        int ou=0,ji=0;
        for(int i=0; i<n; i++)
        {

            if(a[i]%2==1)
                ji++;
            ou+=a[i]/2;
        }
        if(ji==0&&ou!=0)
            cout<<ou*2<<endl;
        else if(ji==0&&ou==0)
            cout<<1<<endl;
        else
        {
            int ans=ou/ji;
            cout<<ans*2+1<<endl;
        }
    }
    return 0;
}

HDU 5744 Keep On Movin (思維題,水題)