1. 程式人生 > >hdu 4561 模擬題

hdu 4561 模擬題

/*
模擬題 
思路: 我的思路是如果一串連續的0,我就存一個0在另外的數組裡面,如果一串連續的2
我就存 多少個2在另外一個數組裡,如果一串連續的-2我就存多少個-2在另外一個數組裡(-2)用負單位儲存
例如:輸入資料為 2,-2,2,2,0,0,-2,-2,-2,2,2,2,-2
我另外一個數組裡面存的則是 1,-1,2,0,-3,3,-1
而計算最大的值 我們只需要把連續是數字的絕對值加起來,然後像上面的話我們加起來最大的應該是
3+3+1  也就是最後三個數字的絕對值。然後我們在用另外一個sum統計負數 的絕對值,
那麼另外一個sum中的值則是 4,另外一個sum 是-3和-1的絕對值。也就是這一連串數字中
負數的個數。然後判斷他是不是偶數,如果是偶數,那麼乘積最大的2就是 7,因為四個負數負負得正了,這樣子連起來是最大的。
還有一種情況 如果是負數的個數為奇數的話,就表示最後乘起來為負數。就得將負數的個數減去1;
例如下面 這組資料。0,-2 -2 2 -2 ,0
這組資料放到另外一個數組裡 為 x[0]=0,x[1]=-2,x[2]= 1,x[3]=-1,a[4]=0
然後連續不為0數絕對值的和尾 4,但是 另外一個sum=3;也就是負數有三個,那麼我們就要減去一個負數。這組資料也好辦。
直接從區間開頭或者結尾減去都可以。所以最終的sum=sum-1;
這種的話。2 2 -2 -2 2 -2 2
x【0】=2,x[1]=-2,x[2]=1,x[3]=-1,x[4]=1;
這種的話就就要分情況討論,因為區間的頭和尾不是負數,所以不能直接減去1.我們要剪去頭和尾,兩者最小的再減去1;
那麼這裡 就等於sum=2+2+1+1+1+1減去min(x[4],x[0])-1=5;
就是純模擬了。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
int a[50010];
int x[50010];
int n;
int main()
{
    int t;
    scanf("%d",&t);
    int cas=1;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int count=1;
        for(int i=1;i<=n;i++)//統計連續相同數字的個數放入x陣列
        {
           int sum=0;
           int j=i;
           for(;a[j]==a[i]&&j<=n;j++)
            {
               sum++;
            }
           if(a[i]==2)  x[count++]=sum;
           else if(a[i]==-2) x[count++]=(-sum);
           else x[count++]=0;
           i=j-1;

        }
      int max=-999999999;
        for(int i=1;i<count;i++)
        {  int sum=0;
           int sum1=0;
           int j=i;
           if(x[i]!=0)
           {
              for(;j<count&x[j]!=0;j++)//將連續不為0的區間和累加起來。
              {
                  if(x[j]<0) sum1+=abs(x[j]);//負數的個數。
                  sum+=abs(x[j]);
              }
              j--;
              if(sum1%2==0)//當負數的個數為偶,和就為sum;
              {
                  if(max<sum) max=sum;
              }
             else
             {
                 if(x[j]<0||x[i]<0) {//當負數的個數奇,並且頭部和尾部有一個是負數。
                                          sum--;
                                          if(max<sum) max=sum;
                                   }
                else if(x[j]>x[i]) {//都不是負數就減去頭部喝尾部連續的整數小的的個數。

                          sum--;
                          sum=sum-x[i];
                          if(max<sum) max=sum;
                         }
                 else
                 {
                     sum--;
                     sum=sum-x[j];
                     if(max<sum) max=sum;
                 }
             }
           }
           i=j;

        }
        if(max==-999999999)  printf("Case #%d: %d\n",cas++,0);
        else printf("Case #%d: %d\n",cas++,max);
    }
}