机试学习笔记05 -- 查找、贪心、链表问题

一、查找问题

1 顺序查找

直接for循环一个个去查,但时间复杂度太大

2 排序+二分

最好用于已经排序好的

#include <bits/stdc++.h>  
using namespace std;  
  
int a[10005];  
int main(){  
    int n,x;  
    scanf("%d", &n);//输入n个数  
    for (int i = 1; i <= n; i++) {  
        scanf("%d", &a[i]);  
    }  
    sort(a+1, a+1+n);//排序保持单调性  
    scanf("%d", &x);//要查找的数x  
    int l = 1, r = n;  
    while (l <= r) {  
        int mid = (l + r) / 2;  
        if (a[mid] == x) {  
            printf("find\n");  
            return 0;  
        }  
        if (a[mid] > x) {//如果x比中间数小  
            r = mid - 1;//说明在左区间  
        }  
        else l = mid + 1;//否则在右区间内  
    }  
    printf("not find\n");  
    return 0;  
}  
3 终极方法:map容器

不用考虑数据类型,不用考虑二分难写。
字符串查找,静态查找

#include<bits/stdc++.h>

using namespace std;

struct node{
	string num;
	string name;
	string sex;
	int age;
};

int main(){
	int n, q;
	map<string, node> M;
	cin >> n;
	for(int i = 0; i < n; ++i){
		node tmp;
		cin >> tmp.num >> tmp.name >> tmp.sex >> tmp.age;
		M[tmp.num] = tmp; // string->node
	}
	cin >> q;
	for(int i = 0; i < q; ++i){
		string m;
		cin >> m;
		if(M.find(m) != M.end()){
			cout << M[m].num << " " << M[m].name << " " << M[m].sex << " " << M[m].age << endl;
		}
		else{
			cout << "No Answer!" << endl;
		}
	}
	return 0; 
} 

动态查找,注意map的索引就是你想查找的东西,比如这道题就是要查找的数(因为想查这个数到底在不在),一个更为简单的确定方法是看题目的输入,和输出。

#include<bits/stdc++.h>

using namespace std;

int main(){
	int n, q, x;
	map<int, int> M; //数的值->数的次数 
	cin >> n;
	for(int i = 0; i < n; ++i){
		cin >> x;
		M[x]++;
	}
	cin >> q;
	for(int i = 0; i < q; ++i){
		cin >> x;
		if(M[x] == 0){
			cout << "no" << endl;
			M[x]++;
		}
		else{
			cout << "find" << endl;
		}
	}
	return 0;
}

二、贪心类问题

主要是思想
每一步完成局部最优解。

#include<bits/stdc++.h>

using namespace std;

struct node{
	double m, w;
}p[1005];

bool cmp(node x, node y){
	return x.w/x.m < y.w/y.m;
}
int main(){
	int x, n;
	while(cin >> x >> n){
		if(x == -1 && n == -1) break;
		for(int i = 0; i < n; ++i){
			cin >> p[i].m >> p[i].w;
		}
		sort(p, p+n, cmp);
		double ans = 0;
		for(int i = 0; i < n; ++i){
			if(x >= p[i].w){
				ans += p[i].m;
				x -= p[i].w;
			}
			else{
				ans += x * p[i].m / p[i].w;
				break;
			}
		}
		printf("%.3lf\n", ans);
	}
	return 0;
}

三、链表类问题

1 猴子报数

首先要会创建链表,然后要会基本删除,最后要注意在删除时如何保留pre节点,不删除时如何保留pre节点。

#include<bits/stdc++.h>

using namespace std;

struct node{
	int num;
	struct node *next;
};

int n, s, m;

struct node *create(){
	struct node *head, *now, *pre;
	for(int i = 1; i <= n; ++i){
		now = (struct node *)malloc(sizeof(node));
		if(i == 1){
			head = now;
			pre = now;
		}
		now->num = i;
		now->next = head;
		pre->next = now;
		pre = now; //把当前节点变为之前节点,进行下一轮 
	} 
	return head;
}

void print(struct node *head){
	struct node *p, *pre;
	p = head;
	s -= 1;
	while(s){
		pre = p;
		p = p->next;
		s--; 
	}
	int i = 1;
	while(p != NULL){
		if(p == p->next){
			printf("%d\n", p->num);
			break;
		}
		if(i%m == 0){
			printf("%d,",p->num);
			pre->next = p->next;
		}
		else pre = p; //如果删除节点了,pre不要动;否则再让pre动 
		p = p->next;
		i++;
	}
} 

int main(){
	while(cin >> n >> s >> m){
		if(n == 0 && s == 0 && m == 0) break;
		struct node *head;
		head = create();
		print(head);
	}
	return 0;
}
2 链表排序

就用冒泡排序,然后交换的是节点数值。

#include<bits/stdc++.h>

using namespace std;

struct Node{
	int Element;
	struct Node *Next;
};

int n;

struct Node *create(){
	struct Node *head, *now, *pre;
	for(int i = 1; i <= n; ++i){
		now = (struct Node *)malloc(sizeof(Node));
		int num;
		cin >> num;
		now->Element = num;
		if(i==1){
			head = now;
			pre = now;
		}
		else{
			pre->Next = now;
			pre = now;
		}
	}
	return head;
}

void print(struct Node *head){
	struct Node *now, *pre, *p;
	now = head;
	pre = now;
	now = now->Next;
	for(int i = 1; i < n; ++i){
		for(int j = 1; j < n; ++j){
			if(pre->Element > now->Element){
				int temp = pre->Element;
				pre->Element = now->Element;
				now->Element = temp;
			} 
			pre = now;
			now = now->Next;
		}
		now = head;
		pre = now;
		now = now->Next;
	}
	p = head;
	for(int i = 1; i <= n; ++i){
		cout << p->Element << " ";
		p = p->Next;
	}
	cout << endl;
}

int main(){
	cin >> n;
	struct Node *head;
	head = create();
	print(head);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值