[SinGuLaRiTy] 复习模板-搜索

Posted SinGuLaRiTy2001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SinGuLaRiTy] 复习模板-搜索相关的知识,希望对你有一定的参考价值。

【SinGuLaRiTy-1043】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

桶排序

void bucketSort(int a[], int n, int max)//a[]为待排序数组,n为数组长度,max为数组中的最大值范围
{
    int i,j;
    int buckets[max];
    // 将buckets中的所有数据都初始化为0。
    memset(buckets, 0, max*sizeof(int));
    // 1. 计数
    for(i = 0; i < n; i++) 
        buckets[a[i]]++; 
    // 2. 排序
    for (i = 0, j = 0; i < max; i++) 
    {
        while( (buckets[i]--) >0 )
            a[j++] = i;
    }
}

优先队列

#include<stdio.h>  
#include<functional>  
#include<queue>  
#include<vector>  
using namespace std;  
//定义结构,使用运算符重载,自定义优先级1  
struct cmp1{  
    bool operator ()(int &a,int &b){  
        return a>b;//最小值优先  
    }  
};  
struct cmp2{  
    bool operator ()(int &a,int &b){  
        return a<b;//最大值优先  
    }  
};  
//定义结构,使用运算符重载,自定义优先级2  
struct number1{  
    int x;  
    bool operator < (const number1 &a) const {  
        return x>a.x;//最小值优先  
    }  
};  
struct number2{  
    int x;  
    bool operator < (const number2 &a) const {  
        return x<a.x;//最大值优先  
    }  
};  
int a[]={14,10,56,7,83,22,36,91,3,47,72,0};  
number1 num1[]={14,10,56,7,83,22,36,91,3,47,72,0};  
number2 num2[]={14,10,56,7,83,22,36,91,3,47,72,0};  
  
int main()  
{   priority_queue<int>que;//采用默认优先级构造队列  
  
    priority_queue<int,vector<int>,cmp1>que1;//最小值优先  
    priority_queue<int,vector<int>,cmp2>que2;//最大值优先  
  
    priority_queue<int,vector<int>,greater<int> >que3;//注意“>>”会被认为错误,  
                                                      //这是右移运算符,所以这里用空格号隔开  
    priority_queue<int,vector<int>,less<int> >que4;////最大值优先  
  
    priority_queue<number1>que5;  
    priority_queue<number2>que6;  
  
    int i;  
    for(i=0;a[i];i++){  
        que.push(a[i]);  
        que1.push(a[i]);  
        que2.push(a[i]);  
        que3.push(a[i]);  
        que4.push(a[i]);  
    }  
    for(i=0;num1[i].x;i++)  
        que5.push(num1[i]);  
    for(i=0;num2[i].x;i++)  
        que6.push(num2[i]);  
  
  
    printf("采用默认优先关系:\n(priority_queue<int>que;)\n");  
    printf("Queue 0:\n");  
    while(!que.empty()){  
        printf("%3d",que.top());  
        que.pop();  
    }  
    puts("");  
    puts("");  
  
    printf("采用结构体自定义优先级方式一:\n(priority_queue<int,vector<int>,cmp>que;)\n");  
    printf("Queue 1:\n");  
    while(!que1.empty()){  
        printf("%3d",que1.top());  
        que1.pop();  
    }  
    puts("");  
    printf("Queue 2:\n");  
    while(!que2.empty()){  
        printf("%3d",que2.top());  
        que2.pop();  
    }  
    puts("");  
    puts("");  
    printf("采用头文件\"functional\"内定义优先级:\n(priority_queue<int,vector<int>,greater<int>/less<int> >que;)\n");  
    printf("Queue 3:\n");  
    while(!que3.empty()){  
        printf("%3d",que3.top());  
        que3.pop();  
    }  
    puts("");  
    printf("Queue 4:\n");  
    while(!que4.empty()){  
        printf("%3d",que4.top());  
        que4.pop();  
    }  
    puts("");  
    puts("");  
    printf("采用结构体自定义优先级方式二:\n(priority_queue<number>que)\n");  
    printf("Queue 5:\n");  
    while(!que5.empty()){  
        printf("%3d",que5.top());  
        que5.pop();  
    }  
    puts("");  
    printf("Queue 6:\n");  
    while(!que6.empty()){  
        printf("%3d",que6.top());  
        que6.pop();  
    }  
    puts("");  
    return 0;  
}  

Set

#include <iostream>
#include <set>

using namespace std;

int main()
{
    set<int> s;
    s.insert(1);
    s.insert(2);
    s.insert(3);
    s.insert(1);
    cout<<"set 的 size 值为 :"<<s.size()<<endl;
    cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;
    cout<<"set 中的第一个元素是 :"<<*s.begin()<<endl;
    cout<<"set 中的最后一个元素是:"<<*s.end()<<endl;
    s.clear();
    if(s.empty())
    {
        cout<<"set 为空 !!!"<<endl;
    }
    cout<<"set 的 size 值为 :"<<s.size()<<endl;
    cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;
    return 0;
}

Map

#include <iostream>
#include <map>

using namespace std;

int main()
{
    // map是一种关联容器类,里面存储的元素类型为pair<const KEY, DATA>。不同的元素KEY值不同。    
    // 定义map及其对应的迭代器
    map<char, int> mapTest;
    map<char, int>::iterator iterTest;
    
    // 在map中插入元素
    // 这种利用下标值的插入方式,当map中没有对应键值的元素时,插入。当map中存在对应键值的元素时,修改其值或者获取其值。
    mapTest[a] = 10;
    mapTest[b] = 20;
    mapTest[c] = 30;
    mapTest[a] = 15;

    // 这种使用insert的插入方式,当map中没有对应键值的元素时,插入。当map中存在对应键值的元素时,不插入元素。
    pair<map<char, int>::iterator, bool> ret;
    mapTest.insert(map<char, int>::value_type(d, 40));
    ret = mapTest.insert(make_pair(d, 50));
    mapTest.insert(make_pair(e, 50));

    // 当使用insert函数后会返回pair<map<char, int>::iterator, bool>类型的值,bool值表示是否插入成功。迭代器指向插入的元素。
    cout << ret.second << endl;
    

    // map中查找某个指定键值的元素,查找成功则返回对应的迭代器。查找失败则返回.end()对应的容器边界迭代器。
    iterTest = mapTest.find(f);
    cout << (iterTest == mapTest.end()) << " find: 0 means success, 1 means failure"<< endl;

    // 正向遍历
    cout << "正向" << endl;
    for (iterTest = mapTest.begin(); iterTest != mapTest.end(); iterTest++)
    {
        cout << iterTest->first << " " << iterTest->second << endl;
    }
    
    // 反向遍历
    cout << "反向" << endl;
    map<char, int>::reverse_iterator iter;
    for (iter = mapTest.rbegin(); iter != mapTest.rend(); iter++)
    {
        cout << iter->first << " " << iter->second << endl;
    }

    // 使用size获取容器中元素个数
    int num;
    num = (int)mapTest.size();
    cout << num << endl;

    // 使用clear清空容器
    mapTest.clear();

    // 使用empty判断容器是否为空
    if (mapTest.empty())
    {
        cout << "The map is empty" << endl;
    }
    
    return 0;
}

Hash

#include <iostream>
#include <cstring>

using namespace std;

const int maxn=11111;
const int maxh=10000019;
int head[maxh];
int next[maxh];
long long st[maxn];

void hash_init()
{
    memset(head,0,sizeof(head));
}

int hash(long long p,int prime=10000019)
{
    int h;
    //hash操作
    h=p%prime;
    return h;
}

bool add_hash(int s)
{
    int h=hash(st[s]);
    int u=head[h];
    while(u)
    {
        //if (memcmp(st[u],st[s],sizeof(st[s]))==0) return 0;
        //if (strcmp(st[u],st[s])==0) return 0;
        if (st[u]==st[s]) return 0;
        u=next[u];
    }
    next[s]=head[h];
    head[h]=s;
    return 1;
}

bool search_hash(long long p)
{
    int h=hash(p);
    int u=head[h];
    while (u)
    {
        //if (memcmp(st[u],p,sizeof(st[u]))==0) return 1;
        //if (strcmp(st[u],str)==0) return 1;
        if (st[u]==p) return 1;
        u=next[u];
    }
    return 0;
}

IDA* (以 埃及分数 为例)

#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 10000
typedef long long LL;
using namespace std;

int maxd;
LL ans[MAXN];
LL v[MAXN];
LL gcd(LL a,LL b){
    return b==0?a:gcd(b,a%b);
}
int get_first(int a,int b){
    if(b%a==0) return b/a;
    else return (b/a+1);
}
bool better(int d){
    return ans[d]==-1||v[d]<ans[d];
}
bool dfs(int d,int from,LL aa,LL bb){
    if(d==maxd){
        if(bb%aa) return false;
        v[d]=bb/aa;
        if(better(d)) memcpy(ans,v,sizeof(LL)*(d+1));
        return true;
    }
    bool ok=false;
    from=max(from,get_first(aa,bb));
    for(int i=from;;i++){
        if(bb*(maxd+1-d)<=i*aa) break;
        v[d]=i;
        LL b2=bb*i;
        LL a2=aa*i-bb;
        LL g=gcd(a2,b2);
        if(dfs(d+1,i+1,a2/g,b2/g)) ok=true;
    }
    return ok;
}
int main(){
    int a,b;
    while(scanf("%d%d",&a,&b)==2){
        for(maxd=1;;maxd++){///ID
            memset(ans,-1,sizeof(ans));
            if(dfs(1,get_first(a,b),a,b)) break;
        }
        for(int i=1;ans[i]!=-1;i++)
            printf("%lld ",ans[i]);
        printf("\n");
    }
    return 0;
}

双向BFS (以 HDU-1195 为例)

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = 2333333; 
const int maxn = 10000 + 5;
vector <int> e[maxn];
int vis[maxn] , dist[maxn];

void solve(int x)
{
    int num[4] , i , tmp , y;
    i = 0;
    tmp = x;
    while(tmp) {
        num[i++] = tmp % 10;
        tmp /= 10;
    }
    for(i = 0 ; i < 4 ; i++)
        if(num[i] == 0)
            return;
    for(i = 0 ; i < 4 ; i++) {
        if(i < 3) {
            swap(num[i] , num[i + 1]);
            y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0];
            e[x].push_back(y);
            e[y].push_back(x);
            swap(num[i] , num[i + 1]);
        }
        tmp = num[i];
        if(num[i] == 9)
            num[i] = 1;
        else
            num[i]++;
        y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0];
        e[x].push_back(y);
        e[y].push_back(x);
        num[i] = tmp;

        if(num[i] == 1) 
            num[i] = 9;
        else
            num[i]--;
        y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0];
        e[x].push_back(y);
        e[y].push_back(x);
        num[i] = tmp;
    }
}
int BFS_2(int start , int end)
{
    if(start == end)
        return 0;
    memset(vis , 0 , sizeof(vis));
    queue <int> que[2];
    vis[start] = 1;
    vis[end] = 2;
    que[0].push(start);
    que[1].push(end);
    dist[start] = dist[end] = 0;
    while(!que[0].empty() && !que[1].empty()) {
        int k = 0;
        if(que[0].size() < que[1].size())
            k++;
        int u = que[k].front();
        que[k].pop();
        for(int i = 0 ; i < e[u].size() ; i++) {
            int j = e[u][i];
            if(!vis[j]) {
                vis[j] = vis[u];
                que[k].push(j);
                dist[j] = dist[u] + 1;
            } else if(vis[j] == vis[u]) {
                continue;
            } else {
                return dist[j] + dist[u] + 1;
            }
        }
    }
    return -1;
}
int main()
{
    int T , a , b;
    for(int i = 1111 ; i <= 9999 ; i++)
        solve(i);
    cin >> T;
    while(T--) {
        scanf("%d %d" , &a , &b);
        printf("%d\n" , BFS_2(a , b));
    }
    return 0;
}

 

Time: 2017-10-28

以上是关于[SinGuLaRiTy] 复习模板-搜索的主要内容,如果未能解决你的问题,请参考以下文章

[SinGuLaRiTy] 复习模板-树

[SinGuLaRiTy] 复习模板-数据结构

[SinGuLaRiTy] 数论题目复习

[SinGuLaRiTy] 贪心题目复习

[SinGuLaRiTy] 分治题目复习

[SinGuLaRiTy] 图论题目复习