1. 程式人生 > >2014北京邀請賽(部分題解)

2014北京邀請賽(部分題解)

names extra php targe set 二進制 osi wan tmp

立即要去比賽了。

今天做了一下2014北京邀請賽。出了兩道題目,感覺非常水啊、、、

首先H題:

H. Happy Reversal

1000ms 1000ms 65536KB 64-bit integer IO format: %lld Java class name: Main Submit Status PID: 34988 Font Size: Elfness is studying in an operation "NOT". For a binary number A, if we do operation "NOT A
", after that, all digits of A will be reversed. (e.g. A=1001101, after operation "NOT A", A will be 0110010). Now Elfness has N binary numbers of length K, now he can do operations "NOT" for some of his numbers. Let‘s assume after his operations, the maximum number is M, the minimum number is P. He wants to know what‘s the maximum M - P he can get. Can you help him?

Input

The first line of input is an integer T (T ≤ 60), indicating the number of cases. For each case, the first line contains 2 integers N (1 ≤ N ≤ 10000) and K (1 ≤ K ≤ 60), the next N lines contains N binary numbers, one number per line, indicating the numbers that Elfness has. The length of each binary number is K.

Output

For each case, first output the case number as "Case #x: ", and x is the case number. Then you should output an integer, indicating the maximum result that Elfness can get.



題意:給出n個二進制串,能夠把當中的一些0和1反轉(即0變1,1變0),找出轉化後n個串中的最大值和最小值的差值。


分析:思路就是把全部的串和反轉的存在一個數組中,然後排序。找最大值和最小值的差,(假設是同一個串反轉的就找第二大的和最小的或第二小和最大的中的最大值)。註意假如僅僅有一個串的話結果為0


代碼:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class number
{
public:
    long long p;
    string s;
    void Set(long long p,string s)
    {
        this->p = p;
        this->s = s;
    }
    friend bool operator < (number a,number b)
    {
        return a.s < b.s;
    }
};
int main()
{
    long long T,c=0;
    cin>>T;
    number num[20020];
    while(T--)
    {
        c++;
        long long n,k;
        cin>>n>>k;
        string s;
        for(long long i = 0; i < 2*n; ++ i)
        {
            cin>>s;
            num[i].Set(i,s);
            for(long long j = 0; j < k; ++ j)
                if(s[j]==‘0‘)
                    s[j]=‘1‘;
                else
                    s[j]=‘0‘;
            ++i;
            num[i].Set(i-1,s);
        }
        sort(num,num+2*n);
//        for(long long i = 0; i < 2*n; ++ i)
//            cout<<num[i].s<<endl;
        cout<<"Case #"<<c<<": ";
        if(n == 1)
        {
            cout<<"0"<<endl;
        }
        else if(num[0].p!=num[2*n-1].p)
        {
            long long a=0,b=0;
            for(long long i = k-1,j=1; i >= 0; -- i,j<<=1)
            {
                if(num[0].s[i] == ‘1‘)
                    a+=j;
            }
            for(long long i = k-1,j=1; i >= 0; -- i,j<<=1)
            {
                if(num[2*n-1].s[i] == ‘1‘)
                    b+=j;
            }
            cout<<b-a<<endl;
        }
        else
        {
            string s1,s2;
            long long a=0,b=0,ans=0;
            s1 = num[0].s;
            s2 = num[2*n-2].s;
            for(long long i = k-1,j=1; i >= 0; -- i,j<<=1)
            {
                if(s1[i] == ‘1‘)
                    a+=j;
            }
            for(long long i = k-1,j=1; i >= 0; -- i,j<<=1)
            {
                if(s2[i] == ‘1‘)
                    b+=j;
            }
            ans = b-a;
            b=0;a=0;
            s1 = num[1].s;
            s2 = num[2*n-1].s;
            for(long long i = k-1,j=1; i >= 0; -- i,j<<=1)
            {
                if(s1[i] == ‘1‘)
                    a+=j;
            }
            for(long long i = k-1,j=1; i >= 0; -- i,j<<=1)
            {
                if(s2[i] == ‘1‘)
                    b+=j;
            }
            cout<<max(ans,b-a)<<endl;
        }
    }
    return 0;
}


B題:

B. Beautiful Garden

15000ms 8000ms 65536KB 64-bit integer IO format: %lld Java class name: Main Submit Status PID: 34982 Font Size: There are n trees planted in lxhgww‘s garden. You can assume that these trees are planted along the X-axis, and the coordinate of ith tree is xi. But in recent days, lxhgww wants to move some of the trees to make them look more beautiful. lxhgww will recognize the trees as beautiful if and only if the distance between any adjacent trees is the same. Now, lxhgww wants to know what is the minimum number of trees he need to move. Just to be clear, after moving, there should still be n trees in the X-axis.

Input

The first line of the input contains a single integer T, which is the number of test cases. For each case,
  • The first line contains an integers number n (1 ≤ n ≤ 40), representing the number of trees lxhgww planted;
  • The second line contains n integers numbers, the ith number represents xi. (-1000000000 ≤ xi ≤ 1000000000)

Output

For each case, first output the case number as "Case #x: ", and x is the case number. Then output a single number, representing the minimum number of trees lxhgww needs to move.



題意:給出一些數。表示數軸上的位置。讓你移動最少的點讓全部相鄰點的差值均相等!

求移動次數


分析:思路就是暴力,由於點僅僅有40個,所以我們可以枚舉相鄰點的差值,由於我最少也可以保證兩個點是不動的,那麽我枚舉這兩個點作為全部的差值,然後找一個落在枚舉的方案的最大點的方案。

此題目坑點非常多!首先有可能兩個點落在同一位置。其次枚舉的話數據範圍會超int。

算是一個坑題。


代碼:

#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
long long a[200];
int main()
{
    long long T;
    scanf("%lld",&T);
    for(long long cas=1;cas<=T;cas++)
    {
        long long n,ans=0;
        scanf("%lld",&n);
        long long len=n;
        for(long long i=0;i<n;i++)  ///輸入
        {
            scanf("%lld",&a[i]);
        }
        sort(a,a+n);
        long long count=0,tmp=1;
        for(long long i=1;i<n;i++)  //找數組中僅僅有兩個數且重點的最小值
        {
            if(a[i]==a[i-1])
            {
                tmp++;
            }
            else
                break;
        }
        long long xx = 0,tt=0;
        int  p = 0;
        for(int i = 0; i < n; ++ i)  //找全部裏面重點最多的
        {
            if(i == n-1)
            {
                ++tt;
                if(xx < tt)
                    xx = tt;
            }
            else if(a[i]==a[p])
            tt++;
            else
            {
                p = i;
                if(xx < tt)
                    xx = tt;
                tt=1;
            }//printf("*%lld\n",tt);
        }
//        printf("x%lld\n",tmp);
        count = min(tmp,len-tmp);
        for(long long i=1;i<n;i++)  ///刪除反復元素
        {
            if(a[i]==a[i-1])
            {
                for(long long j=i;j<n-1;j++)
                    a[j]=a[j+1];
                n--;i--;
            }
        }
//        for(long long i=0;i<n;i++)
//            printf("%lld ",a[i]);
        for(long long i=0;i<n-1;i++)  ///枚舉結果
        {
            for(long long j=i+1;j<n;j++)
            {
                long long lis=a[j]-a[i];
//                if(lis==0)
//                    continue;
                for(long long k=0;k<n;k++)
                {
                    long long mm=0;
                    long long ri=a[k]+(len-1)*lis;
//                    printf("x%lld ",ri);
                    for(long long f=k;f<n && a[f]<=ri;f++)
                    {
//                        if(f==i || f==j)
//                            continue;
                        long long tmp=a[f]-a[i];
                        if(tmp<0)
                            tmp=-tmp;
                        if(tmp%lis==0)
                            mm++;
                    }
//                    printf("%lld\n",mm);
                    if(mm>ans)
                        ans=mm;
                }
            }
//            printf("xx\n\n");
        }
        printf("Case #%lld: ",cas);
        if(n==1 || len==2)
        {
            printf("0\n");continue;
        }
        else if(n==2 && len>2)
        {
            printf("%lld\n",count);continue;
        }
        printf("%lld\n",min(len-ans,len-xx));
    }
    return 0;
}


2014北京邀請賽(部分題解)