2017年11月1日刷题记录 | 普及组

写在前面

哇Cys好菜啊!

哇Cys连普及组都不会打了啊!

哇要Noip了好紧脏啊!

哇Cys要开始刷题

然后重点是Cys好菜菜菜菜菜菜啊!!!!

以下题目来自题库比赛

Task-1  A-B

题目描述

出题是一件痛苦的事情!

题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的A+B Problem,改用A-B了哈哈!

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1:
4 1
1 1 2 3
输出样例#1:
3

说明

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

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

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

解题思路

  • 对于90%的数据,容易得出我们可以直接用两重for循环暴力枚举求得,复杂度为O(N²)
  • 即:
  • 而对于100%的数据,N高达200000.
  • 做题的时候并没有什么想法,只是想到要不排序一遍?然后再阉割一下这个数列,减少一下循环次数?
  • 深入考虑又发现了这个思路的不可做性
  • 于是转而考虑用一个桶的思想
  • 考虑将每个读入的数计入,再考虑一个数+C是否有出现(即有被计数)
  • 如果有即证明已经存在一对数
  • 那么只需要O(N)扫描一遍即可
  • 总体复杂度O(N)

关于代码

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3  
 4 using namespace std;
 5  
 6 LL Read()
 7 {
 8     LL val = 0, opt = 1;
 9     char ch;
10     while (!(isdigit( ch = getchar() ) || ch == '-'));
11     if (ch == '-') opt =-1;
12     else val = ch - '0';
13     while (isdigit( ch = getchar() )) (val *= 10) += ch - '0';
14     return val * opt;
15 }
16  
17 map <LL , LL> Que;
18 LL Wsy[200222];
19 int main()
20 {
21     
22     ios::sync_with_stdio(0);
23        
24        LL N , C;
25        N = Read();
26        C = Read();
27        for (LL i = 1; i <= N ; ++i){
28            cin >> Wsy[i];
29         Que[Wsy[i]]++;
30     }
31     
32        LL Key = 0;
33 
34     for (register LL i = 1 ; i <= N ; ++i)
35         if (Que[Wsy[i]+C] > 0) Key+=Que[Wsy[i]+C];
36        
37     cout << Key;
38     
39     return 0;
40 }
A-B

 

 

Task-2  A-B

 

解题思路

 

关于代码

 

A-B
posted @ 2017-11-01 11:25  Yuns's  阅读(345)  评论(0编辑  收藏  举报