Codeforces #205前三题

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
*/



你可能感兴趣的:(codeforces)