【算法设计-查找】查找的相关题目
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;
}