洛谷P1102《A-B数对》

原创建时间:2018-02-01 21:31:22

普及- 的“水”题

题目地址

提前说明:本题难度为普及-

题目描述

给出一串数以及一个数字C,要求计算出所有A-B=C的数对的个数。(不同位置的数字一样的数对算不同的数对)

输入输出格式

输入格式

第一行包括2个非负整数N和C,中间用空格隔开。

第二行有N个整数,中间用空格隔开,作为要求处理的那串数。

输出格式

输出一行,表示该串数中包含的所有满足A-B=C的数对的个数。

输入输出样例

输入输出样例1

input:

4 1
1 1 2 3

output:

3

数据说明

对于73%的数据,N <= 2000;

对于100%的数据,N <= 200000。

所有输入数据都在longint范围内。

原题目2017/4/29新添数据两组

解析

暴力解法

粗略一看,这道题是不是特别水?

只需要用\(O(n^2)\)的暴力解法不就可以了吗?

​ 枚举A和B,再判断A-B是否为C

但是!

你们Naive,没看见那个N<=200000

这样肯定会TLE的啊喂

测试记录 76分

正确解法

作为C++选手,我们一定要发扬光大Alexander留给我们的STL

于是我们就可以用std::map映射来做这道题目(注意这是普及-的题目)

将A-B=C转换为A-C=B,然后找这N个数中有几个B就行了

测试记录 AC

代码实现

暴力解法

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int *arr,n,c;

inline void read(){
  ios::sync_with_stdio(false);
  cin >> n >> c;
  arr = new int[n];
  for (int i = 0;i < n;i++){
    cin >> arr[i];
  }
  return;
}

inline int work(){
  int ans = 0;
  for(int i = 0;i < n;i++)
    for (int j = 0;j < n;j++)
      if ((arr[i] - arr[j] == c)) ans++;
  return ans;
}

int main(int argc, char const *argv[]) {
  read();
  cout << work() << endl;
  return 0;
}

正确解法

#include <cstdio>
#include <map>
using namespace std;
int a[200001];

inline void LetMeAccept(){
  int n,c;
  scanf("%d %d",&n,&c);
  map<int,int> p;
  for(int i = 0;i < n;i++){
    scanf("%d",a + i);
    p[a[i]]++;
  }
  long long ans=0;
  for(int i = 0;i < n;i++)
    ans += p[a[i] + c];
  printf("%lld\n",ans);
}

int main(int argc,char const *argv[]){
    LetMeAccept();
    return 0;
}

posted @ 2019-10-26 19:43  Handwer  阅读(216)  评论(0编辑  收藏  举报