一、查找问题
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;
}