Codeforces #205前三題

果7發表於2013-10-11
A. Domino
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Valera has got n domino pieces in a row. Each piece consists of two halves — the upper one and the lower one. Each of the halves contains a number from 1 to 6. Valera loves even integers very much, so he wants the sum of the numbers on the upper halves and the sum of the numbers on the lower halves to be even.

To do that, Valera can rotate the dominoes by 180 degrees. After the rotation the upper and the lower halves swap places. This action takes one second. Help Valera find out the minimum time he must spend rotating dominoes to make his wish come true.

Input

The first line contains integer n (1 ≤ n ≤ 100), denoting the number of dominoes Valera has. Next n lines contain two space-separated integers xi, yi (1 ≤ xi, yi ≤ 6). Number xi is initially written on the upper half of the i-th domino, yi is initially written on the lower half.

Output

Print a single number — the minimum required number of seconds. If Valera can't do the task in any time, print  - 1.

Sample test(s)
input
2
4 2
6 4
output
0
input
1
2 3
output
-1
input
3
1 4
2 3
4 4
output
1
Note

In the first test case the sum of the numbers on the upper halves equals 10 and the sum of the numbers on the lower halves equals 6. Both numbers are even, so Valera doesn't required to do anything.

In the second sample Valera has only one piece of domino. It is written 3 on the one of its halves, therefore one of the sums will always be odd.

In the third case Valera can rotate the first piece, and after that the sum on the upper halves will be equal to 10, and the sum on the lower halves will be equal to 8.


     很久沒打CF了。。
    題目大意:給你n張牌,每張牌上面下面會各有一個1~6的數字。對任意一張牌可以操作使得上下兩個數字顛倒,問你至少操作幾次,使得上面數字總和為偶數,下面數字總和也為偶數。如果不存在就直接輸出-1.

     解題思路:開始無腦直接統計上面偶數下面偶數,上面奇數,下面偶數。。。這樣四類的個數分別為cnt1,cnt2,cnt3,cnt4,再判斷,不過忽略了一種情況,cnt4為奇數,cnt2=cnt3=0的時候無法轉換牌,沒有牌可以轉換,這個時候應該輸出-1。。。。後來自己又認真考慮了一下這個問題,其實可以開始就可以把所有上面的總和統計出來,下面的數字總和統計出來,然後分析,這樣會簡單很多。。。NC了。。。

     題目地址:A. Domino

AC程式碼:
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;


int main()
{
    int n,i;
    int cnt1,cnt2,cnt3,cnt4;
    int a,b;
    while(~scanf("%d",&n))
    {
        cnt1=cnt2=cnt3=cnt4=0;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            if(a%2==0&&b%2==0) cnt1++;
            if(a%2==1&&b%2==0) cnt2++;
            if(a%2==0&&b%2==1) cnt3++;
            if(a%2==1&&b%2==1) cnt4++;
        }
        if(cnt2+cnt3==0&&cnt4%2==1)
           puts("-1");
            
            else if(cnt4%2==0)
            {
                if((cnt2+cnt3)%2==1) puts("-1");
                else if(cnt2%2==0) puts("0");
                else puts("1");
            }
            else
            {
                if((cnt2+cnt3)%2==1) puts("-1");
                else if(cnt2%2==0) puts("1");
                else puts("0");
            }
    }
    return 0;
}


B. Two Heaps
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Valera has n cubes, each cube contains an integer from 10 to 99. He arbitrarily chooses n cubes and puts them in the first heap. The remaining cubes form the second heap.

Valera decided to play with cubes. During the game he takes a cube from the first heap and writes down the number it has. Then he takes a cube from the second heap and write out its two digits near two digits he had written (to the right of them). In the end he obtained a single fourdigit integer — the first two digits of it is written on the cube from the first heap, and the second two digits of it is written on the second cube from the second heap.

Valera knows arithmetic very well. So, he can easily count the number of distinct fourdigit numbers he can get in the game. The other question is: how to split cubes into two heaps so that this number (the number of distinct fourdigit integers Valera can get) will be as large as possible?

Input

The first line contains integer n (1 ≤ n ≤ 100). The second line contains n space-separated integers ai (10 ≤ ai ≤ 99), denoting the numbers on the cubes.

Output

In the first line print a single number — the maximum possible number of distinct four-digit numbers Valera can obtain. In the second line print n numbers bi (1 ≤ bi ≤ 2). The numbers mean: the i-th cube belongs to the bi-th heap in your division.

If there are multiple optimal ways to split the cubes into the heaps, print any of them.

Sample test(s)
input
1
10 99
output
1
2 1 
input
2
13 24 13 45
output
4
1 2 2 1 
Note

In the first test case Valera can put the first cube in the first heap, and second cube — in second heap. In this case he obtain number1099. If he put the second cube in the first heap, and the first cube in the second heap, then he can obtain number 9910. In both cases the maximum number of distinct integers is equal to one.

In the second test case Valera can obtain numbers 1313, 1345, 2413, 2445. Note, that if he put the first and the third cubes in the first heap, he can obtain only two numbers 1324 and 1345.


題目大意:比賽的時候半天都沒看懂TAT題目的大意是給你2*n個數字,每個數字大小都是10~99,把他分成兩堆使得組成不同四位數的個數最多。要求分成1,2堆之後,每次只能從1堆取一個作為高二位,二堆取一個作為低二位。

解題思路:把每個數出現的次數先統計出來,儘量把相同的分到兩堆。 然後最大的個數就由出現過一次或者兩次的數字決定了,即程式碼中的sum,如果出現一次,分到一堆即可,出現兩次,分到兩堆,出現三次及以上,兩個以外的可以直接拋棄了。 不過在分堆的時候老是WA掉,我是直接把個數出現一次或者兩次及以上的都直接一起處理掉。

題目地址:B. Two Heaps


先看一下WA了無數次的程式碼,這個題目真的長記性。。
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[205];
int p[205];
int ans[205];

int main()
{
    int n,i,j,res,sum;
    while(~scanf("%d",&n))
    {
        sum=0;
        memset(p,0,sizeof(p));  //把個數都歸為0
        memset(ans,0,sizeof(ans));
        for(i=0;i<2*n;i++)
        {
            scanf("%d",&a[i]);
            p[a[i]]++;
            if(p[a[i]]<=2) sum++;  //上面下面各分配一個為2,否則為1
        }
        if(sum%2)  res=(sum/2)*(sum/2+1);
        else res=(sum/2)*(sum/2);
        int k=1;
        for(i=10;i<100;i++)
        {
            if(p[i])
            {
                for(j=0;j<2*n;j++)
                {
                    if(a[j]==i)
                    {
                        ans[j]=k;  //第一次為1,則下一次為2
                        k=3-k;
                    }
                }
            }
        }
        cout<<res<<endl;
        cout<<ans[0];
        for(i=1;i<2*n;i++)
            cout<<" "<<ans[i];
        cout<<endl;
    }
    return 0;
}

在群裡面問了一下@Joy,他說可能是因為統計個數為1的數目的時候使得個數為>=2的數目不能夠平分。自己琢磨了一下。自己sum/2*sum/2或者sum/2*(sum/2+1)是建立在個數平分的基礎上,比如1 1 1 2 3 3 3 4這樣的資料,把個數大於等於2的先統計,這樣結果是9,但是按照自己的寫法卻是8. 感謝cxlove的資料!!自己那樣並沒有達到真正所謂的平分。

AC程式碼:
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[205];
int p[205];
int ans[205];

int main()
{
    int n,i,j,res,sum;
    while(~scanf("%d",&n))
    {
        sum=0;
        memset(p,0,sizeof(p));  //把個數都歸為0
        memset(ans,0,sizeof(ans));
        for(i=0;i<2*n;i++)
        {
            scanf("%d",&a[i]);
            p[a[i]]++;
            if(p[a[i]]<=2) sum++;  //上面下面各分配一個為2,否則為1
        }

        if(sum%2)  res=(sum/2)*(sum/2+1);
        else res=(sum/2)*(sum/2);
        int k=1;
        for(i=10;i<100;i++)
        {
            if(p[i]>=2)   //先統計個數大於1的
            {
                for(j=0;j<2*n;j++)
                {
                    if(a[j]==i)
                    {
                        ans[j]=k;  //第一次為1,則下一次為2
                        k=3-k;
                    }
                }
            }
        }

        for(i=0;i<2*n;i++)
        {
            if(!ans[i])  //個數為1的
            {
                ans[i]=k;
                k=3-k;
            }
        }

        cout<<res<<endl;
        cout<<ans[0];
        for(i=1;i<2*n;i++)
            cout<<" "<<ans[i];
        cout<<endl;
    }
    return 0;
}

/*
2
13 24 13 45
4
12 12 12 34 34 45 56 67
6
12 34 34 34 34 45 45 45 67 67 67 67
*/



C. Find Maximum
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Valera has array a, consisting of n integers a0, a1, ..., an - 1, and function f(x), taking an integer from 0 to 2n - 1 as its single argument. Value f(x) is calculated by formula , where value bit(i) equals one if the binary representation of number xcontains a 1 on the i-th position, and zero otherwise.

For example, if n = 4 and x = 11 (11 = 20 + 21 + 23), then f(x) = a0 + a1 + a3.

Help Valera find the maximum of function f(x) among all x, for which an inequality holds: 0 ≤ x ≤ m.

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of array elements. The next line contains n space-separated integersa0, a1, ..., an - 1 (0 ≤ ai ≤ 104) — elements of array a.

The third line contains a sequence of digits zero and one without spaces s0s1... sn - 1 — the binary representation of number m. Numberm equals .

Output

Print a single integer — the maximum value of function f(x) for all .

Sample test(s)
input
2
3 8
10
output
3
input
5
17 0 10 2 1
11010
output
27
Note

In the first test case m = 20 = 1, f(0) = 0, f(1) = a0 = 3.

In the second sample m = 20 + 21 + 23 = 11, the maximum value of function equals f(5) = a0 + a2 = 17 + 10 = 27.



題目大意:給你一個陣列a,存放n個數,a[i]>=0,然後給你一個二進位制串m,由低位到高位給出,問你0~m個數裡面,使得sum最大。sum+=a[i](m[i]=='1')

解題思路:開始思維短路,WA了幾次想清楚了,最大值肯能出現在每一個1變為0,左邊的可全變為1,右邊的保持。具體見程式碼。

題目地址:C. Find Maximum

AC程式碼:
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
char b[100005];
int p[100005];
int dp[100005];   //dp[i]記錄的是a[i]之前的所有和
int dp2[100005];  //dp2[i]記錄的是a[i]*(b[i]=='1')之前的所有和

int main()
{
    int n,i;
    int sum;
    while(~scanf("%d",&n))
    {
        sum=0;
        for(i=0;i<n;i++)
           scanf("%d",&a[i]);

        dp[0]=a[0];
        for(i=1;i<n;i++)
            dp[i]=dp[i-1]+a[i];
        scanf("%s",b);
        if(b[0]=='1') dp2[0]=a[0];
        else dp2[0]=0;
        for(i=1;i<n;i++)
        {
            if(b[i]=='1')
                dp2[i]=dp2[i-1]+a[i];
            else
                dp2[i]=dp2[i-1];
        }

        int t=0;
        for(i=n-1;i>=1;i--)
              if(b[i]=='1')
              {
                  p[t++]=i;
              }

        for(i=0;i<n;i++)
            if(b[i]=='1')
                sum+=a[i];

        //cout<<sum<<endl;
        for(i=0;i<t;i++)   //每次碰到1把當前改為0,前面全為1,後面不變
        {
            //cout<<p[i]<<endl;
            int tmp=0;
            int x=p[i];
            tmp=dp[x-1];
            tmp=tmp-dp2[x]+dp2[n-1];
            if(tmp>sum)
                sum=tmp;
        }
        printf("%d\n",sum);
    }
    return 0;
}

/*
2
3 8
10
5
17 0 10 2 1
11010
12
17 0 10 2 1 17 0 10 2 1 4 5
101000111101
*/



相關文章