CCF201409-1 相邻数对(100分)序列处理

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF201409-1 相邻数对(100分)序列处理相关的知识,希望对你有一定的参考价值。

试题编号: 201409-1
试题名称: 相邻数对
时间限制: 1.0s
内存限制: 256.0MB
问题描述:

问题描述
  给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1。
输入格式
  输入的第一行包含一个整数n,表示给定整数的个数。
  第二行包含所给定的n个整数。
输出格式
  输出一个整数,表示值正好相差1的数对的个数。
样例输入
6
10 2 6 3 7 8
样例输出
3
样例说明
  值正好相差1的数对包括(2, 3), (6, 7), (7, 8)。
评测用例规模与约定
  1<=n<=1000,给定的整数为不超过10000的非负整数。

问题链接CCF201409-1 相邻数对
问题简述:(略)
问题分析
重写解题博客以及解题程序代码(参见参考链接),解题逻辑更加清晰,解题代码更加简洁,多种解法顺序更加合理。
解法一:标记数组
由于输入的数据各不相同,并且输入数据为不超过10000的非负整数,这样就可以用一个下标0-10001的数组flag[]作为标记数组,数组flag[]所有元素的初值均为0,出现过a则flag[a]置值为1。每当读入一个数a,判定一下是否为相邻数并且进行计数就可以了。只有数据值的范围比较小时,才可以用数组来进行标记,否则数组过长存储溢出。
需要强调的一点是,程序员应该显式地第变量进行初始化,而不是依赖于缺省的初始化。这是一个编程原则问题。
解法二:排序
对输入数据进行排序,然后再顺序判定数是否相邻,并且进行统计计数就好了,也是一种解决办法。这种办法有点杀鸡用牛刀的感觉,但是可以借这个解法学习一下STL的算法函数sort()的应用。
这种解法也可以不用考虑数据值的范围。
解法三:暴力搜索
暴力法也称为枚举法,被公认是一种速度慢的做法,其时间复杂度为O(n2)。然而,如果找不到好方法,有时候枚举法就是最好的方法。说是暴力搜索,还是要尽量避免重复计算,能少算一点算一点。计算量减半全靠循环控制了,一种基本的编程技巧。
解法四:用集合set来实现
用STL的set来存放已经出现的数,也是一种好的做法。每当读入一个数,只需要判定一下相邻的数是否已经在集合里就可以了。这种解法可以不用考虑数据值的范围,只是程序计算时间和空间上代价会略为大一些。可以借这个解法学习一下set的应用。
也可以用STL的map来解决这个问题,类似于做标记,不如set简单。
用Python语言程序解题
用Python语言主要用于解决应用问题,可以不必太考虑程序效率,只要程序逻辑清晰即可。可以暴力搜索,也可以排序后再处理。
用Python语言程序来解这个题,从道理上来说,上述四种解法都可以有。
用Java语言程序解题
用Java语言程序来解这个题,从道理上来说,上述四种解法都可以有。给出一种题解程序,还可以有各种各样程序写法。
程序说明:(略)
参考链接
CCF201409-1 相邻数对(100分)
题记:(略)

100分的C语言程序(解法一:标记数组)如下:

/* CCF201409-1 相邻数对 */

#include <stdio.h>
#include <string.h>

#define N 10000
int flag[N + 2]; /* 标记数组:flag[i]=1表示i已经出现过,flag[i]=0表示i尚未出现过 */

int main(void)
{
    memset(flag, 0, sizeof (flag)); /* 清除标志数组flag[],使其每个元素均为0 */

    int n, a, cnt = 0;
    scanf("%d", &n);
    while (n--) {
        scanf("%d", &a); /* 读入数据 */
        flag[a] = 1;
        if (flag[a - 1]) cnt++; /* 判断和统计:小1的数已经存在 */
        if (flag[a + 1]) cnt++; /* 判断和统计:大1的数已经存在 */
    }
    printf("%d\\n", cnt); /* 输出结果 */

    return 0;
}

100分的C++语言程序(解法二:排序)如下:

/* CCF201409-1 相邻数对 */

#include <iostream>
#include <algorithm>

using namespace std;

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

int main(void)
{
    int n, cnt = 0;
    cin >> n;
    for (int i=0; i<n; i++) cin >> a[i]; // 读入数据

    sort(a, a + n); // 排序

    for (int i = 1; i < n; i++)
        if (a[i] - a[i - 1] == 1) cnt++; // 判定相邻,统计计数

    cout << cnt << endl; // 输出结果

    return 0;
}

100分的C++语言程序(解法三:暴力搜索)如下:

/* CCF201409-1 相邻数对 */

#include <stdio.h>

#define N 1000
int a[N];

int main(void)
{
    int n, cnt = 0, i, j;
    scanf("%d", &n);
    for (i = 0; i < n; i++) scanf("%d", &a[i]); /* 读入数据 */

    /* 暴力搜索 */
    for (i = 0; i < n; i++)
        for (j = i + 1; j < n; j++)
            if (a[i] - a[j] == 1 || a[j] - a[i] == 1) cnt++;

    printf("%d\\n", cnt); /* 输出结果:不会重复计数 */

    return 0;
}

100分的C++语言程序(解法四:用集合set来实现)如下:

/* CCF201409-1 相邻数对 */

#include <iostream>
#include <set>

using namespace std;

int main()
{
    set<int> st;
    int n, a, cnt = 0;
    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> a; // 读入数据
        if (st.find(a - 1) != st.end()) cnt++; // 判定a-1存在,统计计数
        if (st.find(a + 1) != st.end()) cnt++; // 判定a+1存在,统计计数
        st.insert(a);
    }
    cout << cnt << endl; // 输出结果

    return 0;
}

100分的Python语言程序(解法三:整数暴力搜索)如下:

#  CCF201409-1 相邻数对

n = int(input())
nums = [int(num) for num in input().split()]
c = 0
for num in nums:
    if num + 1 in nums:
        c += 1
print(c)

100分的Python语言程序(解法二:整数排序)如下:

#  CCF201409-1 相邻数对

n = int(input())
nums = [int(num) for num in input().split()]
nums.sort() # 排序
c = 0
for i in range(n - 1):
    if (nums[i + 1] - nums[i] == 1):
        c += 1
print(c)

100分的Java语言程序(解法四:用集合Set来实现)如下:

/* CCF201409-1 相邻数对 */

import java.util.Scanner;
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;

public class Main {
	public static void main(String args[]){
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		Set<Integer> set = new HashSet<>();
		for (int i = 0; i < n; i++) set.add(input.nextInt());

		int cnt = 0;
		Iterator<Integer> iterator = set.iterator();
		while (iterator.hasNext())
			if (set.contains(iterator.next() + 1)) cnt++;

		System.out.println(cnt);
	}
}

以上是关于CCF201409-1 相邻数对(100分)序列处理的主要内容,如果未能解决你的问题,请参考以下文章

CCF CSP 201409-1 相邻数对

CCF_201409-1_相邻数对

201409-1 相邻数对 Java

CCF201712-1 最小差值(100分)序列处理

CCF201703-1 分蛋糕(100分)序列处理

CCF202112-1 序列查询(100分)序列处理