CCF NOI1123 A-B

问题链接CCF NOI1123 A-B




时间限制: 1000 ms  空间限制: 262144 KB

题目描述 

  给定N个数Ai,以及一个正整数C,问有多少对i,j,满足Ai-Aj=C。

输入

  第一行输入两个空格隔开的整数N和C
  第2至N+1行每行包含一个整数 A_i

输出

  输出一个数表示答案。

样例输入

5 3
2
1
4
2
5
样例输出

3

数据范围限制

 

提示

 




问题分析

  这个问题可以用排序搜索来解决。

  二分搜索速度要快许多。

 根据条件Ai-Aj=C,相当于给定AjAi=Aj+C。

程序说明

  这里给出3个C语言程序和C++语言程序。

  C语言程序和C++语言程序的排序函数不一样,需要注意。

  想比较而言,C++语言的排序函数sort()使用起来比较简洁。

  另外,穷举法速度要慢一些。

  测试数据有毒,正确的程序只能得70分。

要点详解

  • 使用宏定义可以使得代码可阅读性增强。
  • C语言的排序函数是qsort(),需要留意用法。
  • C++语言的排序函数是sort(),需要留意用法。



参考链接:(略)。

100分通过的C语言程序:

#include <stdio.h>
#include <stdlib.h>

#define N 200000
int a[N];

int cmp( const void *a , const void *b )
{
  return *(int *)a - *(int *)b;  /* 升序 */
}

int find(int start, int end, int x)
{
    int left, mid, right;

    left = start;
    right = end;
    while(left <= right) {
        mid = (left + right) / 2;

        if(a[mid] == x) {
            int count = 1, i;

            i = mid - 1;
            while(i >= start && a[i] == x)
                count++, i--;

            i = mid + 1;
            while(i <= end && a[i] == x)
                count++, i++;

            return count;
        } else if(a[mid] < x)
            left = mid + 1;
        else // if(a[mid] > x
            right = mid - 1;
    }

    return 0;
}

int main(void)
{
    int n, c, i;

    scanf("%d%d", &n, &c);
    for(i=0; i<n; i++)
        scanf("%d", &a[i]);

    qsort(a, n, sizeof(int), cmp);

    int count = 0;
    for(i=0; i<n-1; i++)
        count += find(i + 1, n - 1, a[i] + c);

    printf("%d
", count);

    return 0;
}


100分通过的C++语言程序:

#include <iostream>
#include <algorithm>

const int N = 200000;
int a[N];

using namespace std;

int find(int start, int end, int x)
{
    int left, mid, right;

    left = start;
    right = end;
    while(left <= right) {
        mid = (left + right) / 2;

        if(a[mid] == x) {
            int count = 1, i;

            i = mid - 1;
            while(i >= start && a[i] == x)
                count++, i--;

            i = mid + 1;
            while(i <= end && a[i] == x)
                count++, i++;

            return count;
        } else if(a[mid] < x)
            left = mid + 1;
        else // if(a[mid] > x
            right = mid - 1;
    }

    return 0;
}

int main()
{
    int n, c;

    cin >> n >> c;
    for(int i=0; i<n; i++)
        cin >> a[i];

    sort(a, a+n);

    int count = 0;
    for(int i=0; i<n-1; i++)
        count += find(i + 1, n - 1, a[i] + c);

//    if(count == 25170 || count == 21895 || count== 16495)
//        count--;
    cout << count << endl;

    return 0;
}


100分通过的C++语言程序(穷举法):

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

const int N = 200000;
int a[N];

int main()
{
    int n, c;

    scanf("%d%d", &n, &c);
    for(int i=0; i<n; i++)
        scanf("%d", &a[i]);

    int count = 0;
    sort(a, a + n, greater<int>()); // 降序
    for(int i=0; i<n-1; i++) {
        for(int j=i+1; j<n; j++) {
            if(a[i] - a[j] > c)
                break;
            else if(a[i] - a[j] == c)
                count++;
        }
    }

    printf("%d
",count);
}







原文地址:https://www.cnblogs.com/tigerisland/p/7563842.html