offer66

有序:二分
串变长:先定长
二叉树:三种遍历,记录路径,深搜时要善于利用返回值(一般不让另外开数组维护)
栈与队列:根据所求开辅助栈
数组寻找而不消耗额外空间:把值取反,或者加上最大值令超限
(即用1变-1,或26个字母的话我就加26,以此表示已访问,且可以获取到原值)
二进制下从低位起逐个1消去:n&=(n-1)
二进制下获取最低位1的位置:n&(-n)
链表:同步指针保持差不变,快针&慢针可以求差值
数组找出次数有关的数字:阵地攻守
数组找连续区间或找两个值:尺取法(即左右针)
字符串计数/全排:逐位深搜
实在没有头绪,可以考虑位操作

……跟ACM有很大的不同就是,不会让你打表,不会让你开很大的数组……
 

下面是今天手撕的模板,有些用不着,有备无患吧

还要补充:多线程

//KMP
#include<bits/stdc++.h>
using namespace std;
int slen,tlen,s[103],t[103],nxt[103];
void getnxt(){
    int k=-1,j=0;
    nxt[0]=-1;
    while(j<tlen){
        if(k==-1||t[k]==t[j])nxt[k++]=j++;
        else k=nxt[k];
    }
}
int kmp_match(){
    getnxt();
    int k=0,j=0;
    while(k<tlen&&j<slen){
        if(k==-1||t[k]==s[j])k++,j++;
        else k=nxt[k];
    }
    if(k==tlen)return j-tlen;
    else return -1;
}
int main(){
    int cas;cin>>cas;
    while(cas--){
        cin>>slen>>tlen;
        for(int i=0;i<slen;i++)cin>>s[i];
        for(int i=0;i<tlen;i++)cin>>t[i];
        int ans=kmp_match();
        if(ans==-1)cout<<ans<<endl;
        else cout<<ans+1<<endl;
    }
    return 0;
}


//heap
#include<bits/stdc++.h>
using namespace std;
int n,tre[103];
void shift_down(int pos){
    int flag=0,nxt;
    while(pos*2<=n&&flag==0){
        nxt=pos;
        if(tre[pos]>tre[pos*2])
            nxt=pos*2;
        if(tre[nxt]>tre[nxt+1])
            nxt=nxt+1;
        if(nxt!=pos){
            int tmp=tre[pos];
            tre[pos]=tre[nxt];
            tre[nxt]=tmp;
            pos=nxt;
        }
        else{
            flag=1;
        }
    }
}
void heap_push(int x){
    n++;
    tre[n]=x;
    int p=n;
    while(tre[p/2]>tre[p]){
        swap(tre[p/2],tre[p]);
        p/=2;
    }
}
int heap_pop(){
    int tmp=tre[1];
    tre[1]=tre[n--];
    shift_down(1);
    return tmp;
}
int main(){
    heap_push(2);heap_push(4);heap_push(3);heap_push(1);heap_push(5);
    cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;
    return 0;
}


//线段树
#include<bits/stdc++.h>
using namespace std;
int tre[1003*4];
int query(int l,int r,int id,int x,int y){
    int ans=0;
    if(x<=l&&r<=y){
        ans+=tre[id];
        return ans;
    }
    int mid=(l+r)/2;
    if(x<=mid)ans+=query(l,mid,id*2,x,y);
    if(y>mid)ans+=query(mid+1,r,id*2+1,x,y);
    return ans;
}
void update(int l,int r,int id,int x,int y){
    if(l>=r){
        tre[id]+=y;
        return ;
    }
    int mid=(l+r)/2;
    if(mid>=x)update(l,mid,id*2,x,y);
    else update(mid+1,r,id*2+1,x,y);
    tre[id]=tre[id*2]+tre[id*2+1];
}
int main(){
    update(1,10,1,2,2);
    update(1,10,1,3,5);
    update(1,10,1,6,7);
    cout<<query(1,10,1,1,10)<<endl;
    cout<<query(1,10,1,2,2)<<endl;
    cout<<query(1,10,1,3,6)<<endl;
    return 0;
}

//去重
#include<bits/stdc++.h>
using namespace std;
int main(){
    int b[10]={1,1,2,2,3,4,5,5,6,7};
    int n=unique(b,b+10)-b;
    for(int i=0;i<n;i++)
        cout<<b[i]<<endl;
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main(){
    vector<int>a={1,1,2,2,3,3,4,4,5,6,7};
    a.erase(unique(a.begin(),a.end()),a.end());
    for(vector<int>::iterator ite=a.begin();ite!=a.end();ite++)
        cout<<(*ite)<<endl;
    return 0;
}

//floyd
#include<bits/stdc++.h>
using namespace std;
int floyd[103][103];
int main(){
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            cin>>floyd[i][j];
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
                if(floyd[i][j]>floyd[i][k]+floyd[k][j])
                    floyd[i][j]=floyd[i][k]+floyd[k][j];
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++)
            cout<<floyd[i][j]<<' ';
        cout<<endl;
    }
    return 0;
}

//dij
#include<bits/stdc++.h>
using namespace std;
struct edge{
    int to;
    int cost;
};
vector<edge>g[103];
typedef pair<int,int> p;
int d[103];
void addedge(int from,int to,int cost){
    g[from].push_back(edge{to,cost});
    g[to].push_back(edge{from,cost});
}
void dij(int s){
    priority_queue<p,vector<p>,greater<p> >pq;
    pq.push(p(0,s));
    memset(d,100,sizeof(d));
    d[1]=0;
    while(!pq.empty()){
        p pp=pq.top();pq.pop();
        int nowp=pp.second;
        if(d[nowp]>pp.first)continue;
        for(int i=0;i<g[nowp].size();i++){
            int newp=g[nowp][i].to;
            int cst=g[nowp][i].cost;
            if(d[newp]>d[nowp]+cst){
                d[newp]=d[nowp]+cst;
                pq.push(p(d[newp],newp));
            }
        }
    }
}
int main(){
    addedge(1,2,3);addedge(1,3,5);addedge(1,4,6);
    addedge(2,3,1);addedge(2,4,3);addedge(3,4,1);
    dij(1);
    cout<<d[1]<<' '<<d[2]<<' '<<d[3]<<' '<<d[4]<<endl;
    return 0;
}

//pri
#include<bits/stdc++.h>
using namespace std;
struct edge{int to;int cost;};
vector<edge>g[103];
typedef pair<int,int> p;
void addedge(int from,int to,int cost){
    g[from].push_back(edge{to,cost});
    g[to].push_back(edge{from,cost});
}
int fa[103],ans;
void prim(int s){
    priority_queue<p,vector<p>,greater<p> >pq;
    pq.push(p(0,s));
    while(!pq.empty()){
        //cout<<fa[1]<<' '<<fa[2]<<' '<<fa[3]<<' '<<fa[4]<<' '<<ans<<endl;
        p pp=pq.top();pq.pop();
        int nowp=pp.second;
        if(nowp!=s&&fa[nowp]==s)continue;
        fa[nowp]=s;
        ans+=pp.first;
        for(int i=0;i<g[nowp].size();i++){
            int newp=g[nowp][i].to;
            int cst=g[nowp][i].cost;
            if(s==fa[newp])continue;
            pq.push(p(cst,newp));
        }
    }
}
int main(){
    addedge(1,2,3);addedge(1,3,5);addedge(1,4,6);
    addedge(2,3,1);addedge(2,4,3);addedge(3,4,1);
    for(int i=1;i<=4;i++)fa[i]=i;
    prim(1);
    cout<<ans<<endl;
    return 0;
}

//kru
#include<bits/stdc++.h>
using namespace std;
struct edge{int from;int to;int cost;};
vector<edge>g;
int fa[103],ans;
int fid(int x){
    if(x==fa[x])return x;
    else return fa[x]=fid(fa[x]);
}
bool cmp(edge a,edge b){
    if(a.cost<b.cost)return true;
    else return false;
}
void kru(){
    sort(g.begin(),g.end(),cmp);
    for(int i=0;i<g.size();i++){
        int x=fid(g[i].from);
        int y=fid(g[i].to);
        if(x==y)continue;
        ans+=g[i].cost;
        fa[x]=y;
    }
}
int main(){
    g.push_back(edge{1,2,3});g.push_back(edge{1,3,5});g.push_back(edge{1,4,6});
    g.push_back(edge{2,3,1});g.push_back(edge{2,4,3});g.push_back(edge{3,4,10});
    for(int i=1;i<=4;i++)fa[i]=i;
    kru();
    cout<<ans<<endl;
    return 0;
}

//全排
#include<bits/stdc++.h>
using namespace std;
int sum=0;
bool check(char s[],int l,int r){
    for(int i=l;i<r;i++){
        if(s[i]==s[r])return false;
    }
    return true;
}
void perm(char s[],int l,int r){
    if(l==r){
        cout<<s<<endl;
        sum++;
    }
    else{
        for(int i=l;i<=r;i++){
            if(check(s,l,i)){
                swap(s[l],s[i]);
                perm(s,l+1,r);
                swap(s[l],s[i]);
            }
        }
    }
}
int main(){
    char s[103];
    cin>>s;
    int len=strlen(s);
    perm(s,0,len-1);
    cout<<sum<<endl;
	return 0;
}

//三分
#include<bits/stdc++.h>
using namespace std;
double f(double x){
    return x*x+9*x+10;
}
int main(){
    double l=-10000,r=10000;
    while(r-l>1e-3){
        double x=l+(r-l)/3;
        double y=l+(r-l)/3*2;
        if(f(x)>f(y))l=x;
        else r=y;
    }
    cout<<l<<' '<<f(l)<<endl;
	return 0;
}
//二分
#include<bits/stdc++.h>
using namespace std;
double f(double x){
    return x*3;
}
int main(){
    double l=-987,r=345;
    while(r-l>1e-3){
        double mid=(l+r)/2;
        if(f(mid)>0)r=mid;
        else l=mid;
    }
    cout<<l<<' '<<f(l)<<endl;
	return 0;
}

//筛素数
#include <bits/stdc++.h>
using namespace std;
int vis[10000],pri[10000];
int main(){
    int d=sqrt(10000.0);
    for(int i=3;i<d;i+=2)
        if(!vis[i])
            for(int j=i*3;j<d;j+=2*i)
                vis[j]=true;
    pri[1]=2;
    for(int id=2,i=3;i<d;i+=2)
        if(!vis[i])pri[id++]=i;
    int n;cin>>n;
    cout<<pri[n]<<endl;
    return 0;
}

//快速幂
#include <bits/stdc++.h>
using namespace std;
int ksm(int x,int y){
    int ans=1;
    while(y>0){
        if(y&1)ans*=x;
        y>>=1;
        x*=x;
    }
    return ans;
}
int main(){
    int x,y;cin>>x>>y;
    cout<<ksm(x,y)<<endl;
    return 0;
}
//矩阵快速幂
#include<bits/stdc++.h>
using namespace std;
struct mat{int m[103][103];}unit;
int n,p;
mat operator*(mat a,mat b){
    mat ans;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            int x=0;
            for(int k=0;k<n;k++){
                x+=a.m[i][k]*b.m[k][j];
            }
            ans.m[i][j]=x;
        }
    }
    return ans;
}
mat pos_mat(mat a,int p){
    mat ans=unit;
    while(p){
        if(p&1)ans=ans*a;
        a=a*a;
        p>>=1;
    }
    return ans;
}
int main(){
    for(int i=0;i<100;i++)unit.m[i][i]=1;
    cin>>n>>p;
    mat a;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>a.m[i][j];
    a=pos_mat(a,p);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++)
            cout<<a.m[i][j]<<' ';
        cout<<endl;
    }
    return 0;
}

//merge_sort
#include <bits/stdc++.h>
using namespace std;
void merge_sort(int a[],int l,int r){
    if(l>=r)return ;
    int mid=(l+r)/2;
    merge_sort(a,l,mid);
    merge_sort(a,mid+1,r);
    int tmp[10],k=l,i=l,j=mid+1;
    while(i<=mid&&j<=r){
        if(a[i]<a[j])tmp[k++]=a[i++];
        else tmp[k++]=a[j++];
    }
    while(i<=mid)tmp[k++]=a[i++];
    while(j<=r)tmp[k++]=a[j++];
    for(int i=l;i<=r;i++)a[i]=tmp[i];
}
int main(){
    int a[10]={9,8,7,6,5,4,3,2,1,0};
    merge_sort(a,0,9);
    for(int i=0;i<10;i++)
        cout<<a[i]<<' ';
    return 0;
}


//字典树
#include<bits/stdc++.h>
using namespace std;
struct node{
    int cnt;
    struct node* nxt[26];
    node(){
        cnt=0;
        for(int i=0;i<26;i++)
            nxt[i]=NULL;
    }
};
node* root;
char str[103][30];
void maketrie(char *s){
    node* p=root;
    node* tmp=NULL;
    for(int i=0;i<strlen(s);i++){
        if(p->nxt[s[i]-'a']==NULL){
            tmp=new node;
            p->nxt[s[i]-'a']=tmp;
        }
        p=p->nxt[s[i]-'a'];
        p->cnt++;
    }
}
void search(char *s){
    node *p=root;
    for(int i=0;i<strlen(s);i++){
        p=p->nxt[s[i]-'a'];
        cout<<s[i];
        if(p->cnt==1)break;
    }
}
int main(){
    root=new node;
    int n;cin>>n;
    for(int i=0;i<n;i++){
        cin>>str[i];
        maketrie(str[i]);
    }
    for(int i=0;i<n;i++){
        cout<<str[i]<<' ';
        search(str[i]);
        cout<<endl;
    }
    return 0;
}
/*
input:
12
carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate

output:
carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值