SCAU 8628 相亲

8628 相亲

时间限制:500MS  内存限制:1000K

题型: 编程题   语言: 无限制

Description

    在咱遥远破旧的小村庄,男女成婚仍是以古老的、传统的模式:相亲,合时辰八字,合得来则订婚,择日
成亲。其中最忽悠的则是合时辰八字,话说是月老决定,实则是根据某条公式,算是否合得来。通过多年
的明察暗访,终于让我知道合地辰八字的公式了。其规则如下:
1、 根据某条公式将时辰八字转化成一个整数num, 为了方便起见,以后就用这个num表示该人的时辰八字。
2、 如果男女双方的时辰八字之和等于一个给定的数sum,则称此对时辰八字合得来。否则相反。
3、 如果时辰八字合不来的人结婚,会被抓去浸猪笼的,因为会被当成是对神的亵渎。
    如此可知,在咱们村一对男女可以结婚的概率是相当的小。现在你的任务是算出咱们村有多少对男女
可以结婚?

Input

第一行输入一个整数T(1<=T<=10),表示样例的个数。
接下来有T个样例,对于每一个样例,第一行输入两个整数n(0<n<10^5),sum(0<sum<=10^8), n 表示
咱们村的人口数,sum 表示给定的和。接下来输入n个人的信息,每个人用两个整数来表示,其中前面一
个表示性别sex(0表示女,1 表示男),后面一个表示其时辰八字num(0<=num<sum,且所有的num
的值各不相同)。为了方便起见,n 个人的信息是按照每个人的num的递增顺序给出的。

Output

输出占一行,表示能结婚的男女对数。(注意:没有同性的可以结婚,咱国家不允许)

Sample Input

1
4 6
0 2 1 3 0 3 1 4

Sample Output

2

Source

王鑫杰

Provider

admin

#include<stdio.h>
#include<string.h>
int female[100020];
int male[100020];
int strm, strw, sumn;
int solve()
{
    //说实话,题目不太严谨,已说明num各不相同,但Sample里已有相同的num(至少也要说明前提是sex一样)
    //因为是已排序输入,min(female[])和max(male[])相加后进行比较,完全可以先排除>sumn的male[],后面的
    //female[]>此刻的female[],无进行比较的意义
    int i, res = 0;
    --strm;
    if(strm<0) return res;
    for(i=0; i<strw; ++i)
    {
        while(female[i]+male[strm] >= sumn)
        {
            if(female[i]+male[strm] == sumn) res++;
            --strm;
            if(strm<0) return res;
        }
    }
    return res;
}



int main()
{
    int i, T, n, sex, num;
    scanf("%d", &T);
    while(T--)
    {
        strm = strw = 0;
        scanf("%d%d", &n, &sumn);
        memset(female, 0, sizeof(female));
        memset(male, 0, sizeof(male));
        for(i=1; i<=n; ++i)
        {
            scanf("%d%d", &sex, &num);
            if(sex) male[strm++] = num;
            else  female[strw++] = num;
        }
    
        printf("%d\n", solve());
    }
    return 0;
}


 

解题报告:

这题WA了3次,最后还是得寻求师兄的帮助,WA的原因是根据我的思路做题时,数组需要开得很大10^8次方,而OJ却是不允许的,其中问了师兄这样的一个问题:

 做一道题,有了思路,然后测试数据也过了,但提交WA了,这时思维会感到很乱,(相比之前我已经有所进步了,现在会写数据测试)再次查看题目的时候,还是会按照以前的想法去思考问题,尽管尽力的避免,但最后还是忽略了你WA的原因(而这原因却还是出现在题目上的),这个问题如何解决?

WA Code
#include<stdio.h>
#include<string.h>
int sum[100000020];
int male[100020];
int main()
{
    int i, j, T, n, sumn, sex, num, count, result;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &sumn);
        memset(sum, 0, sizeof(sum));
        memset(male, 0, sizeof(male));
        for(i=1,count=0; i<=n; ++i)
        {
            scanf("%d%d", &sex, &num);
            if(sex) male[count++] = sumn - num;
            else  sum[num]++;
        }
        for(i=0,result=0; i<count; ++i)
        if (sum[male[i]] > 0) 
        {
           ++result;
           --sum[male[i]];
        }
        printf("%d\n", result); 
    }
    return 0;
}

师兄的回答是:这个有很多的经验和知识的积累才能够掌握的。 步轻云 18:04:47 不是一两个月就能培养好的能力

这个问题最直接的原因还是赤裸裸的体现在少做题的问题上,所以,无他,尽力培养自己的思维能力。

原文地址:https://www.cnblogs.com/liaoguifa/p/2775542.html