ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模版题ac

2021-06-26 17:57:29  阅读:156  来源: 互联网

标签:ac cout int 模版 namespace cin mid num


acwing

787第k 个数

快速排序

#include<bits/stdc++.h>
using namespace std;
void quick_sort(int n[], int l, int r){
    if(l>=r) return ;
    int i=l-1,j=r+1,x=n[l+r>>1];
    while(i<j){
        do i++; while(n[i]<x);
        do j--; while(n[j]>x);
        if(i<j) swap(n[i],n[j]);
    }
    quick_sort(n,l,j); quick_sort(n,j+1,r);
}
int main(){
    int n[1000001];
    int k,num;
    cin>>num>>k;
    for(int i=0;i<num;i++){
        scanf("%d",&n[i]);
    }
    quick_sort(n,0,num-1);
    cout<<n[k-1];
    return 0;
}

787归并排序

#include<bits/stdc++.h>
using namespace std;
void merge_sort(int num[],int l,int r){
    if(l>=r) return ;
    int mid=l+r>>1;
    merge_sort(num,l,mid);
    merge_sort(num,mid+1,r);
    int k=0;i=l;j=mid+1;
    int tmp[10001];
    while(i<=mid&&j<=r){
        if(num[i]<=num[j]) tmp[k++]=num[i++];
        else tmp[k++]=num[j++];
    }
    while(i<=mid) tmp[k++]=num[i++];
    while(j<=r) tmp[k++]=num[j++];
    for(i=l,j=0;i<=r;i++,j++){
        q[i]=tmp[j];
    }  
}
int mian(){
    int n,num[100001];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>num[i];
    }
    merge_sort(num,0,n-1);
    for(int i=0;i<n;i++){
        cout<<num[i]<<" ";
    }
    return 0;
}

788逆序对的数量

#include<bits/stdc++.h>
using namespace std;

int tmp[100010];
long long int merge_sort(int q[],int l, int r){
    if(l>=r) return 0;
    int mid=l+r>>1;
    long long int res=0;
    res=merge_sort(q,l,mid)+merge_sort(q,mid+1,r);//左边和右边的和加起来

    int k=0,i=l,j=mid+1;
    while(i<=mid&&j<=r){
        if(q[i]<=q[j]) tmp[k++]=q[i++];
        else{
            tmp[k++]=q[j++];
            res+=mid-i+1;
        }
    }
    while(i<=mid) tmp[k++]=q[i++];
    while(j<=r) tmp[k++]=q[j++];
    for(i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];//只有两边都是有序的才能排序
    return res;
}
int main(){
    int n;
    cin>>n;
    int q[100010];
    for(int i=0;i<n;i++){
        cin>>q[i];
    }
    cout<<merge_sort(q,0,n-1);
}

795前缀和

#include<bits/stdc++.h>
using namespace std;
int s[100100];
void create(int num[],int n){
    for(int i=1;i<=n;i++){
        s[i]=s[i-1]+num[i];
    }
}
int main(){
    int n,m;
    
    int b,e;
    cin>>n>>m;
    int num[100010];
    for(int i=1;i<=n;i++){
        scanf("%d",&num[i]);
    }
    create(num,n);
    while(m--){
        cin>>b>>e;
        cout<<s[e]-s[b-1]<<endl;
        
    }
}

796子矩阵的和

#include<iostream>
using namespace std;
int main(){
    int m,n,q;
     int num[1001][1001];
     int s[1001][1001];
    cin>>m>>n>>q    ;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            cin>>num[i][j];
        }
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+num[i][j];
        }
    }
    int x1,x2,y1,y2;
    while(q--){
        cin>>x1>>y1>>x2>>y2;
        cout<<s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]<<endl;
    }
    return 0;
}

789数的范围

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,q,m;
    int num[100010];
    cin>>n>>q;
    for(int i=0;i<n;i++) cin>>num[i];
    while(q--){
        cin>>m;
        int l=0,r=n-1;
        while(l<r){
            int mid=l+r>>1;//r=l-1
            if(num[mid]>=m ) r = mid;//找右边界。如果中间值大于该值,那么说明边界应该在mid的左边。让右边界等于mid。这个地方不用加一。r=l+r=l,变了,还是可以的
            else l=mid+1;
        }
        if(num[l]!=m) cout<<"-1 -1"<<endl;
        else {
            cout<<l<<" ";
            l=0,r=n-1;
            while(l<r){
                int mid=l+r+1>>1;//但这里l=l+r/2=l,l=l.死循环了
                if(num[mid]<=m) l=mid;
                else r=mid-1;
            }
            cout<<l<<endl;
        }
    }
    return 0;
}

790数的三次方根

#include<iostream>
using namespace std;
int main(){
    double l=-10000,r=10000;
    
    double n;
    cin>>n;
    while(r-l>1e-8){
        double m=(l+r)/2;
        if(m*m*m>=n) r=m;
        else l=m;
    }
    printf("%.6lf",l);
}

797差分

#include<bits/stdc++.h>
using namespace std;
int a[100010],b[100010],s[100010];//原数组和差分数组

void insert(int l,int r,int c){
    b[l]+=c;
    b[r+1]-=c;//后面的可以理解,前面的自己模拟一下就行了
}

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++) insert(i,i,a[i]);
    int left,right,val;
    while(m--){
        cin>>left>>right>>val;
        insert(left,right,val);
    }
    
    for(int i=1;i<=n;i++) b[i]+=b[i-1];
    
    for(int i=1;i<=n;i++) cout<<b[i]<<" ";
    
    return 0;
}

799最长相同子序列

#include<bits/stdc++.h>
using namespace std;
int main(){
    int m[100010],n;
    int res=0;
    cin>>n;
        map<int,int> s;
    for(int i=0;i<n;i++) {
        cin>>m[i];
    }
    for(int i=0,j=0;i<n;i++){
        s[m[i]]++;//
        while(s[m[i]]>1){
            s[m[j]]--;
            j++;
        }
        res=max(res,i-j+1);
    }
    cout<<res;
} 

800数组的目标和

#include<bits/stdc++.h>
using namespace std;
int main(){
    int l1,l2,x;
    int a[100010],b[100010];
    cin>>l1>>l2>>x;
    for(int i=0;i<l1;i++) cin>>a[i];
    for(int i=0;i<l2;i++) cin>>b[i];
    for(int i=0,j=l2-1;i<l1;i++){//按照单调性,j从第二个数组的最右端开始往左找,找到最左的能够满足加和大于目标的
        
      
        while(j>0&&a[i]+b[j]>x){
            j--;
        }
        if(a[i]+b[j]==x) {
            cout<<i<<" "<<j;
            break;
        }
    }
    return 0;
}

801二进制中1的个数

#include<bits/stdc++.h>
using namespace std;
int main(){
    int res=0;
    int n,m;
    cin>>n;
    while(n--){
        cin>>m;
        res=0;
        while(m>0){
            if(m%2==1) res++;
            m/=2;
        }
        cout<<res<<" ";
    }
    return 0;
}

802区间和(有点难)

挺复杂的感觉,需要自己模拟一下看好理解一些

#include<bits/stdc++.h>
using namespace std;


typedef pair<int,int> PII;//pair类型保存两个操作
vector<int> alls;	//所有的插入操作和查询操作
vector<PII> add,query;	//定义这两个操作集
int a[300010],s[300010]={0};//len add+2*query定义这两个用来离散化。a的值对应的是alls中的值,对应上
int find(int x){	//二分查找到该点的下标位置作为all数组的索引,就是把alls里面的很多数投射到a里面,再通过alls去索引查找
    int l=0,r=alls.size()-1;
    
    while(l<r){
        int mid=l+r >>1;
        
        if(x<=alls[mid]) r=mid;
        else l=mid+1;
    }
    return r+1;//从1开始
}

int main(){
    int m,n;
    cin>>m>>n;
    int x,c;
    for(int i=0;i<m;i++){
        cin>>x>>c;
        add.push_back({x,c});
        alls.push_back(x);
    }
    int l,r;
    for(int i=0;i<n;i++){
        cin>>l>>r;
        query.push_back({l,r});
        alls.push_back(l);alls.push_back(r);//把待查询的和add的都加进去。重点还是查询部分的。因为去重就可以把
    }
    sort(alls.begin(),alls.end());
    alls.erase(unique(alls.begin(),alls.end()),alls.end());//去重操作,先排序。
    for(auto item : add){
        int x=find(item.first);
        a[x]+=item.second;
    }
    for(int i=1;i<=alls.size();i++){
        s[i]=s[i-1]+a[i];//计算离散后的前缀和
    }
    for(auto item : query){
        int l=find(item.first);
        int r=find(item.second);
        cout<<s[r]-s[l-1]<<endl;
    }
    
    return 0;
}

803区间合并

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
void merge(vector<PII> &segs){

    vector<PII> res;
    int st=-2e9,ed=-2e9;//有点坑,这里要设置成最小否则后面判断会出问题。最小是-2e9
    sort(segs.begin(),segs.end());//容易拉下,先对所有的线段排序再从里面往外取。
   
    for(auto seg : segs)
        if(ed<seg.first)//没交集
        {
            if(st!=-2e9) res.push_back({st,ed});//防止是第一个
            st=seg.first;ed=seg.second; //加进去之后,开始往下看别的线段
        }
        else ed=max(ed,seg.second); //否则就让ed等于ed和seg里面最大的一个
    
    if(st!=-2e9) res.push_back({st,ed});//最后一个的处理。最后一个假如没合并的话不会进循环了。所以要单独判断
    
    segs=res;
    
}
int main(){
    
    int n;
    cin>>n;
    vector<PII> segs;
    int l,r;
    for(int i=0;i<n;i++){
        cin>>l>>r;
        segs.push_back({l,r});
    }

    merge(segs);
    
    cout<<segs.size();
    return 0;
    
}

830单调栈

#include<bits/stdc++.h>
using namespace std;
//找出每个数左边离他最近的比他大/小的数
int n;
int stk[100010];
int tt;
int main(){
    cin>>n;
    int x;
    for(int i=0;i<n;i++){
        cin>>x;
        while(tt&&stk[tt]>=x) tt--;//找比当前数小最近的数。栈里面的值比当前的数要大,说明之后就可以不用考虑了,直接把小数放进去其他的弹出来就可以了
        if(tt) cout<<stk[tt]<<" ";
        else cout<<-1<<" ";
        stk[++tt]=x;
    }
    return 0;
}

154滑动窗口

#include<bits/stdc++.h>
using namespace std;


int a[1000010],q[1000010];
int main(){
    int n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++) cin>>a[i];
    int hh=0,tt=-1;
    for(int i=0;i<n;i++){
        if(hh<=tt&&q[hh]<i-k+1) hh++; //保证队列始终在窗口内部,队头不能太小了,出来就把队头的删掉。
        while(hh<=tt&&a[q[tt]]>=a[i]) tt--;   //如果队尾元素大于当前元素,那就不用要了没啥用了
        q[++tt]=i;//把这个数加进队列里面去
        if(i>=k-1) cout<<a[q[hh]]<<" ";
    }
    cout<<endl;
     hh=0;tt=-1;
    for(int i=0;i<n;i++){
        if(hh<=tt&&q[hh]<i-k+1) hh++; //保证队列始终在窗口内部,队头不能太小了,出来就把队头的删掉。
        while(hh<=tt&&a[q[tt]]<=a[i]) tt--;   //如果队尾元素小于当前元素,说明窗口里面这个数肯定不会用到了,直接删掉
        q[++tt]=i;//把这个数加进队列里面去
        if(i>=k-1) cout<<a[q[hh]]<<" ";
    }
    cout<<endl;
    return 0;
}

842排列数字

DFS方法

#include<bits/stdc++.h>
using namespace std;
int n;

bool st[10];
int path[10];

void dfs(int u){
    if(u==n) {  //1-n的排列应该有n个数。每一层就会多一个数,因此到n层就该停止了
        for(int i=0;i<n;i++){
            cout<<path[i]<<" ";//path只保留当前数量等于n的路径上的数组内的元素
        }
        cout<<endl;
        return;
    }
    
    else{
        for(int i=1;i<=n;i++){//开始从1遍历
            if(!st[i]){//首先判断待加入的这个是不是遍历过了。1一开始没有,加进去
            path[u]=i;  
            st[i]=true;//更新维护这个状态,然后去下一层dfs1。在第二层时1用过了,还剩2和3,到第三层dfs2,仅剩3,因此123
                        //出来,dfs3输出,返回到dfs2,去看3,3被占用,解除,退回dfs1,dfs1支持3,因此132,重复后,回到dfs
                        //1,结束,在看st全部解锁,放2上去,锁2看13这样类推
            dfs(u+1);
            st[i]=false;
            }
        }
        
        
    }
}

int main(){
    cin>>n;
    dfs(0);
    
    
}

标签:ac,cout,int,模版,namespace,cin,mid,num
来源: https://blog.csdn.net/weixin_43537073/article/details/117018467

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有