G
N
I
D
A
O
L

【算法设计-查找】查找的相关题目

1. 打印极值点下标

【描述】在一个整数数组上,对于下标为i的整数,如果它大于所有它相邻的整数, 或者小于所有它相邻的整数,则称该整数为一个极值点,极值点的下标就是i。

【输入描述】每个案例第一行为此数组元素个数k(4<k<80),第二行是k个整数,每两个整数之间用空格分隔

【输出描述】每个案例输出为n个数字(其中n为该案例中极值点的个数):每个数字对应相应数组的相应极值点下标值,下标值之间用空格分隔。

【示例1】

输入:

10
10 12 12 11 11 12 23 24 12 12
15
12 12 122 112 222 211 222 221 76 36 31 234 256 76 76 
15
12 14 122 112 222 222 222 221 76 36 31 234 256 76 73

输出:

0 7
2 3 4 5 6 10 12
0 2 3 10 12 14

【题解】

#include <stdio.h>

int main(){
	int n;
	int a[80] = {0};
	
	while (scanf("%d", &n) != EOF){
		for (int i = 0; i < n; i++)
			scanf("%d", &a[i]);
			
		for (int i = 0; i < n; i++){
			if (i == 0){
				if (a[0] != a[1])
					printf("%d ", i);
			}
			else if (i == n-1){
				if (a[i] != a[i-1])
					printf("%d ", i);
			}
			else{
				if ((a[i-1] > a[i] && a[i] < a[i+1]) || (a[i-1] < a[i] && a[i] > a[i+1]))
					printf("%d ", i);
			}
		}
		
		printf("\n");
	}
	
	return 0;
}

2. 找最小数

【描述】第一行输入一个数n,1 <= n <= 1000,下面输入n行数据,每一行有两个数,分别是x y。输出一组x y,该组数据是所有数据中x最小,且在x相等的情况下y最小的。

【输入描述】输入有多组数据。 每组输入n,然后输入n个整数对。

【输出描述】输出最小的整数对。

【示例1】

输入:

5  
3 3  
2 2  
5 5  
2 1  
3 6

输出:

2 1

【题解】两次排序

#include <stdio.h>
#include <algorithm>

typedef struct{
	int x;
	int y;
} Data;

bool rule (Data d1, Data d2){
	if (d1.x < d2.x){
		return true;
	}	
	else if (d1.x == d2.x){
		if (d1.y < d2.y)
			return true;
		else 
			return false;
	}
	else{
		return false;
	}
}

int main(){
	int n;
	Data d[1000];
	
	while(scanf("%d", &n) != EOF){
		for (int i = 0; i < n; i++)
			scanf("%d %d", &d[i].x, &d[i].y);
		std::sort(d, d+n, rule);
		printf("%d %d", d[0].x, d[0].y);
	}
	
	return 0;
}

3. 查找

【描述】输入数组长度 n 输入数组 a[1...n] 输入查找个数m 输入查找数字b[1...m] 输出 YES or NO 查找有则YES 否则NO 。

【输入描述】输入有多组数据。 每组输入n,然后输入n个整数,再输入m,然后再输入m个整数(1<=m,n<=100)。

【输出描述】如果在n个数组中输出YES否则输出NO。

【示例1】

输入:

5
1 5 2 4 3
3
2 5 6

输出:

YES
YES
NO

【题解】二分查找

#include <stdio.h>
#include <algorithm>
using namespace std;

#define NUM 50

int Search (int A[], int low, int high, int target){
	int mid;
	while (low <= high){
		mid = low + (high - low) / 2;
		if (A[mid] > target)
			high = mid - 1;
		else if (A[mid] < target)
			low = mid + 1;
		else
			return mid;
	}
	return -1;
}

int main(){
	int n, m, target;
	int a[50] = {0};
	
	while (scanf("%d", &n) != EOF){
		for (int i = 0; i < n; i++)
			scanf("%d", &a[i]);
			
		sort(a, a+n);
		
		scanf("%d", &m);
		for (int i = 0; i < m; i++){
			scanf("%d", &target);
			if (Search(a, 0, n-1, target) != -1)
				printf("YES!\n");
			else
				printf("NO!\n");
		}
	}
		
	return 0;
}

4. 找位置

【描述】对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13。

【输入描述】输入包括一个由字母和数字组成的字符串,其长度不超过100。

【输出描述】可能有多组测试数据,对于每组数据, 按照样例输出的格式将字符出现的位置标出。 1、下标从0开始。 2、相同的字母在一行表示出其出现过的位置。

【示例1】

输入:

abcaaAB12ab12

输出:

a:0,a:3,a:4,a:9
b:1,b:10
1:7,1:11
2:8,2:12

【题解1】拉链法哈希表(我这里是手写了一个哈希表,实际上可以直接调用C++库里的哈希表)

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;

#define NUM 128

typedef struct Node{  // 拉链结点 
	int index;   // 记录该字符出现的位置 
	Node *next;  // 指向下一个节点 
} Node;

typedef struct{
	int cnt;	 // 该字符出现次数 
	Node *head;  // 记录头结点 
	bool isRead; // 记录该字符的结果是否输出过,防止重复输出
} Record;	

int main(){
	string s;
	Record r[NUM];	// 拉链法哈希表(索引/关键字:ASCII码) 
	
	cin >> s;
	int len = s.size();
	
	// 初始化哈希表 
	for (int i = 0; i < NUM; i++){	
		r[i].cnt = 0;
		r[i].head = (Node *) malloc(sizeof(Node));  // 为方便节点插入操作,建立头节点,默认字符出现位置为-1 
		r[i].head->index = -1;
		r[i].head->next = NULL;
		r[i].isRead = false;
	}
	
	// 建立拉链法的哈希表数据结构 
	for (int i = 0; i < len; i++){
		r[s[i]].cnt++;  // 字符出现一次,加1 
		Node *p = (Node *) malloc(sizeof(Node));
		p->index = i;   // 建立拉链结点,插入到对应的拉链中 
		p->next = NULL;
		Node *q;
		for (q = r[s[i]].head; q->next != NULL; q = q->next);
		q->next = p;
	}
	
	// 读取哈希表 
	for (int i = 0; i < len; i++){
		if (r[s[i]].cnt > 1 && !r[s[i]].isRead){
			r[s[i]].isRead = true;   // 标记该字符已经被读取过 
			Node *q = r[s[i]].head;  // 开始遍历拉链 
			while (q != NULL){
				if (q->index != -1 && q->next != NULL)  // 如果不是最后一个节点,需要输出逗号 
					printf("%c:%d,", s[i], q->index);
				else if (q->index != -1 && q->next == NULL) // 如果是最后一个节点,不用输出逗号
					printf("%c:%d", s[i], q->index); 
				q = q->next;
			}
			printf("\n");
		}
	}
	
	return 0;
}

【题解2】(取自牛客网上的题解)二维数组map

(注:两个题解在思路上本质是一样的)

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>

using namespace std;

vector<int> arr[128];
bool visited[128]; 

void Init(string str) {//将字符串所有字符统计一遍
    for(int i=0; i<str.size(); i++) {
        arr[str[i]].push_back(i);
    }
}

int main() {
    string str;
    while(cin>>str) {
        memset(arr,0,sizeof(arr));
        memset(visited,false,sizeof(visited));//初始化为没访问过
        Init(str);

        for(int i=0;i<str.size();i++){//遍历字符串 (为了按字符串出现顺序输出)
            if(!visited[str[i]]&&arr[str[i]].size()>1){//如果是没有访问过的字符 且 是重复的字符 
                for(int j=0;j<arr[str[i]].size();j++){
                    if(j==0){    //输出控制
                        printf("%c:%d",str[i],arr[str[i]][j]);
                    }else {
                        printf(",%c:%d",str[i],arr[str[i]][j]);
                    }
                }
                printf("\n");
                visited[str[i]]=true; //置访问过
            }
        }
    }
    return 0;
}
posted @ 2023-03-02 21:48  漫舞八月(Mount256)  阅读(40)  评论(0编辑  收藏  举报