(模板2)基础算法模板

打表-年份日期问题
//y为年份,m为月份,d为日期
w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7+1
//每年的1,2月要当成上一年的13,14月去算
//例如,1901年1月1日应该当成1900年13月1日
#include<bits/stdc++.h>
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int weeks[7];
int main(){
    int n;cin>>n;
    int days=0;
    for(int year=1900;year<1900+n;year++){
        for(int i=1;i<=12;i++){
            weeks[(days+12)%7]++;
            days+=months[i];
            if(i==2){
                if(year%100!=0&&year%4==0||year%400==0){
                    days++;
                }
            }
        }
    }
    for(int i=5,j=1;j<=7;j++,i=(i+1)%7)    
        cout<<weeks[i]<<" ";
    return 0;
}

多关键字比较
重载<
#include<bits/stdc++.h>
using namespace std;
const int N=310;
struct Person{
    int id,sum,a,b,c;
    bool operator<(const Person t) const{
        if(sum!=t.sum) return sum>t.sum;
        if(a!=t.a) return a>t.a;
        else return id<t.id;
    }
}q[N];
int main(){
    int n;cin>>n;
    for(int i=1;i<=n;i++){
        int a,b,c;
        cin>>a>>b>>c;
        q[i]={i,a+b+c,a,b,c};
    }
    sort(q+1,q+1+n);
    for(int i=1;i<=5;i++){
        cout<<q[i].id<<" "<<q[i].sum<<endl;
    }
    
    return 0;
}
自定义cmp函数
#include<bits/stdc++.h>
using namespace std;
const int N=310;
struct Person
{
    int id,sum,a,b,c;
}q[N];
bool cmp(Person a,Person b){
    if(a.sum!=b.sum) return a.sum>b.sum;
    if(a.a!=b.a) return a.a>b.a;
    else return a.id<b.id;
}
int main(){
    int n;cin>>n;
    for(int i=1;i<=n;i++){
        int a,b,c;
        cin>>a>>b>>c;
        q[i]={i,a+b+c,a,b,c};
    }
    sort(q+1,q+1+n,cmp);
    for(int i=1;i<=5;i++){
        cout<<q[i].id<<" "<<q[i].sum<<endl;
    }
    return 0;
}
快速排序
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n;
int q[N];
void quick_sort(int q[],int l,int r){
	if(l>=r) return ;
	int x=q[l+r >>1],i=l-1,j=r+1;
	while(i<j){
		do i++;while(q[i]<x);
		do j--;while(q[j]>x);
		if(i<j) swap(q[i],q[j]);
	}	
	quick_sort(q,l,j);
	quick_sort(q,j+1,r);
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++) scanf("%d",&q[i]);
	quick_sort(q,0,n-1);
	for(int i=0;i<n;i++) cout<<q[i]<<" ";
	return 0;
}
归并排序
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n;
int q[N]; 
int tmp[N];

void merge_sort(int q[],int l,int r){
     if(l>=r) return ;
     int mid=l + r >>1;
     
     merge_sort(q,l,mid);
     merge_sort(q,mid+1,r);
     
     int i=l,k=0,j=mid+1;
     while(i<=mid&&j<=r){
         if(q[i]<=q[j]) tmp[k++]=q[i++];
         else tmp[k++]=q[j++];
     } 
     while(i<=mid)  tmp[k++]=q[i++];
     while(j<=r)  tmp[k++]=q[j++];
     
     for(i=l,k=0;i<=r;i++,k++) q[i]=tmp[k];
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++) scanf("%d",&q[i]);
	merge_sort(q,0,n-1);
	for(int i=0;i<n;i++) printf("%d ",q[i]); 
	return 0;
}
二分查找
整数二分
#include<bits/stdc++.h>
using namespace std;
int q[100100];
int l,r;
int search_right(int l,int r,int x){
	while(l<r){
		int mid=(l + r )>>1;
		if(q[mid]>=x) r=mid;
		else l=mid+1;
	}
	return l;
}
int search_left(int l,int r,int x){
	while(l<r){
		int mid=(l + r + 1)>>1;
		if(q[mid]<=x) l=mid;
		else r=mid-1;
	}
	return l;
}
int main(){
	int n,m;cin>>n>>m;
	for(int i=0;i<n;i++) cin>>q[i];

	while(m--){
		int x;cin>>x;
		l=0,r=n-1;
		int l1=search_right(l,r,x);
		if(q[l1]!=x) 
		{
		    cout<<"-1 -1"<<endl;
		    continue;
		    
		}
		else 
		{
		    cout<<l1<<" ";
		    
		}
		
		l=0,r=n-1;
		int l2=search_left(l,r,x);		
		cout<<l2<<endl;
	}
	return 0;
}

lower_bound,upper_bound
  1. lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
  2. upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。upper_bound最后结果可能要减1
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N];
int n,q;
int main(){
    cin>>n>>q;
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    while(q--){
        int t;cin>>t;
        int x=lower_bound(a,a+n,t)-a;
        int y=upper_bound(a,a+n,t)-a;
        if(a[--y]==t) cout<<x<<" "<<y<<endl;
        else cout<<-1<<" "<<-1<<endl;
    }
    return 0;
}

浮点二分
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n,m;
int q[N];
bool check(double mid){
    int cnt=0;
    for(int i=0;i<n;i++){
        cnt+=q[i]/mid;
    }
    if(cnt>=m) return true;
    else return false;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>q[i];
    sort(q,q+n);
    double l=0,r=q[n-1];
    while(r-l>1e-4){//比要求的精度少两位
        double mid=(l+r)/2;
        if(check(mid)) l=mid;//在于check函数
        else r=mid;
    }
    printf("%.2lf\n",r);
    return 0;
}

进制转换 、回文数、字母和数字转换
#include<bits/stdc++.h>
using namespace std;
char get(int n){
    if(n<=9) return n+'0';
    return n-10+'A';
}
string base(int n,int b){
    string num;
    while(n){
        num+=get(n%b);
        n/=b;
    }
    reverse(num.begin(),num.end());
    return num;
}
bool check(string num){
    for(int i=0,j=num.size()-1;i<j;i++,j--){
        if(num[i]!=num[j]){
            return false;
        }
    }
    return true;
}

int main(){
    int b;cin>>b;
    for(int i=1;i<=300;i++){
        string num=base(i*i,b);
        if(check(num)){
            cout<<base(i,b)<<" "<<num<<endl;
        }
    }
    return 0;
}

其他进制转换成10进制
int uget(char c){//字符转换成数字
	if(c<='9') return c-'0';
	return c-'A'+10;
}
int base10(string num,int b){//秦九韶算法
	int res=0;
	for(int i=0;i<=num.size()-1;i++){
        char c=num[i];
		res=res*b+uget(c);
	}	
return res;
}

高精度:
加法
#include<bits/stdc++.h>
using namespace std;
vector<int> add(vector<int>&A,vector<int>&B){
	vector<int> C;
	int t=0;
	for(int i=0;i<A.size()||i<B.size();i++){
		if(i<A.size()) t+=A[i];
		if(i<B.size()) t+=B[i];
		C.push_back(t%10);
		t/=10;
	}
	if(t) C.push_back(1);
	return C;
}
int main(){
	string a,b;
	vector<int> A,B;
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
	for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');

	vector<int> C=add(A,B);
	for(int i=C.size()-1;i>=0;i--) cout<<C[i];
	
	
	return 0;
}

减法
乘法
vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

除法
前缀和
一维
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n,m;
int a[N],s[N];
int main(){
	ios::sync_with_stdio(false);//用于cin加快输入
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
	while(m--){
		int l,r;
		cin>>l>>r;
		cout<<s[r]-s[l-1]<<endl;
	}
	return 0;
}
二维
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m,q;
int a[N][N],s[N][N];
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++) 
		for(int j=1;j<=m;j++)
			cin>>a[i][j];
			
	for(int i=1;i<=n;i++) 
		for(int j=1;j<=m;j++)
			s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
			
	while(q--){
		int x1,y1,x2,y2;
		cin>>x1>>y1>>x2>>y2;
		cout<<s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]<<endl;
	}
	return 0;
}
差分
一维
#include<bits/stdc++.h>
using namespace std;
const int N=100100;
int n,m;
int a[N],b[N];
void insert(int l,int r,int c){
	b[l]+=c;
	b[r+1]-=c;
}
int main(){
	ios::sync_with_stdio(false);
	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]);//建立初始b[i]; 
	while(m--){
		int l,r,c;
		cin>>l>>r>>c;
		insert(l,r,c);
	}
	for(int i=1;i<=n;i++) b[i]+=b[i-1];//求前缀和 
	for(int i=1;i<=n;i++) cout<<b[i]<<””;
	return 0;
}

二维
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m,q;
int b[N][N],a[N][N];

void insert(int x1,int y1,int x2,int y2,int c){
	b[x1][y1]+=c;
	b[x2+1][y1]-=c;
	b[x1][y2+1]-=c;
	b[x2+1][y2+1]+=c; 
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			insert(i,j,i,j,a[i][j]);
		}
	}
	while(q--){
		int x1,y1,x2,y2,c;
		cin>>x1>>y1>>x2>>y2>>c;
		insert(x1,y1,x2,y2,c);
	}		
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<b[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

双指针
//简单模板:
for(i=0;j=0;i<n;i++){
	while(j<i&&check(i,j))j++; 
}

//根据空格分隔字符
#include<bits/stdc++.h>
using namespace std;
int main(){
	char str[1000];
	gets(str);
	int n=strlen(str);
	for(int i=0;i<n;i++){
		int j=i;
		while(j<n&&str[j]!=' ')j++;
//根据题意
		for(int k=i;k<j;k++) cout<<str[k];
		cout<<endl;
		i=j;
	} 
	
	return 0;
}
//最长不重复子序列
#include<bits/stdc++.h>
using namespace std;
const int N=100100;
int a[N],s[N];
int n;
int main(){
	cin>>n;
	int res=0;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0,j=0;i<n;i++){
		s[a[i]]++;
		while(s[a[i]]>1){
			s[a[j]]--;
			j++;
		}
		res=max(res,i-j+1);
	}
	cout<<res<<endl;
	return 0;
}

位运算
n的二进制第 k位表示是几
//先把第k位移到最后一位 n>>k
//看一下个位是几 n&1
//合起来n>>k&1
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n=10;
	for(int k=3;k>=0;k--)cout<<(n>>k & 1 );
	return 0;
}
统计二进制1的个数
//lowbit(x):返回x的最后一位1
#include<bits/stdc++.h>
using namespace std;
int lowbit(int x){
	return x & -x;//x&(~x+1)
}
int main(){
	int n;cin>>n;
	while(n--){
		int x;cin>>x;
		int res=0;
		while(x){
			x-=lowbit(x);//每次减去最后一位1 
			res++;
		}
		cout<<res<<" ";
	}
	return 0;
}

离散化
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=300010; //因为l,r也要查询,也要放在数组中,即使它的值是0;
int n,m;
int a[N],s[N];//前缀和 数组们
vector<int> alls;
vector<PII> add,query;//添加和查询

int find(int x){
	int l=0,r=alls.size()-1;
	while(l<r){
		int mid=(l+r)>>1;
		if(alls[mid]>=x) r=mid;
		else l=mid+1;
	}
	return r+1; 
} 
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		int x,c;
		cin>>x>>c;
		add.push_back({x,c});
		alls.push_back(x); 
	}
	for(int i=0;i<m;i++){
		int l,r;
		cin>>l>>r;
		query.push_back({l,r});
		
		alls.push_back(l);//因为l,r也要查询
		alls.push_back(r);
	}
	sort(alls.begin(),alls.end()); 
	alls.erase(unique(alls.begin(),alls.end()),alls.end());
	for(vector<PII>::iterator item=add.begin();item!=add.end();item++){
		int x=find((*item).first);//find是要查找在alls 的位置
		a[x]+=(*item).second;
	} 

/*
for(int i=0;i<add.size();i++){
		int x=find(add[i].first);
		a[x]+=add[i].second;
	} 
*/

	for(int i=1;i<=alls.size();i++) s[i]=s[i-1]+a[i];
	
	for(vector<PII>::iterator item=query.begin();item!=query.end();item++){
		int l=find((*item).first);
		int r=find((*item).second);
		cout<<s[r]-s[l-1]<<endl;
	}

/*
for(int i=0;i<query.size();i++){
		int l=find(query[i].first);
		int r=find(query[i].second);
		cout<<s[r]-s[l-1]<<endl;
	}
*/
	return 0;
}

区间合并
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
vector<PII> segs;

void merge(vector<PII> &segs){
	vector <PII> res;
	sort(segs.begin(),segs.end());
	int st=-2e9,ed=-2e9;
	for(int i=0;i<segs.size();i++){
		if(ed<segs[i].first){
			if(st!=-2e9) res.push_back({st,ed});
			st=segs[i].first;
			ed=segs[i].second;
		} 
		else ed=max(segs[i].second,ed);
	}
	if(st!=-2e9) res.push_back({st,ed});
	segs=res;
}

int main(){
	int n;cin>>n;
	for(int i=0;i<n;i++){
		int l,r;
		cin>>l>>r;
		segs.push_back({l,r});
	}	
	merge(segs);
	cout<<segs.size()<<endl;
	return 0;
}
//422. 校门外的树
#include<bits/stdc++.h>
using namespace std;
const int N=110;
struct Segment{
	int l,r;
	bool operator< (const Segment& t) const
	{
		return l<t.l;
	}
}seg[N];
int main(){
	int n,m;cin>>m>>n;
	for(int i=0;i<n;i++) cin>>seg[i].l>>seg[i].r;
	sort(seg,seg+n);
	int sum=0;
	int L=seg[0].l,R=seg[0].r;
	for(int i=1;i<n;i++){
		if(seg[i].l<=R) R=max(R,seg[i].r);
		else{
			sum+=R-L+1;
			L=seg[i].l,R=seg[i].r;
		}
	}
	sum+=R-L+1; 
	cout<<m+1-sum<<endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * (有向)图的深度优先遍历算法模板 */ package dsa; public abstract class DFS extends GraphTraverse { //变量 protected static int clock = 0;//遍历过程中使用的计时钟 //构造方法 public DFS(Graph g) { super(g); } //深度优先遍历算法 protected Object traverse(Vertex v, Object info) {//从顶点v出发,做深度优先查找 if (UNDISCOVERED != v.getStatus()) return null;//跳过已访问过的顶点(针对非连通图) v.setDStamp(clock++); v.setStatus(DISCOVERED); visit(v, info);//访问当前顶点 for (Iterator it = v.outEdges(); it.hasNext();) {//检查与顶点v Edge e = (Edge)it.getNext();//通过边e = (v, u) Vertex u = (Vertex)e.getVPosInV(1).getElem();//相联的每一顶点u switch (u.getStatus()) {//根据u当前的不同状态,分别做相应处理 case UNDISCOVERED ://若u尚未被发现,则 e.setType(TREE);//e被归类为“树边” traverse(u, info);//从u出发,继续做深度优先查找 break; case DISCOVERED ://若u已经被发现,但对其访问尚未结束,则 e.setType(BACKWARD);//将e归类为“后向跨边” break; default ://VISITED,即对u的访问已经结束 if (u.getDStamp() < v.getDStamp())//若相对于v,u被发现得更早,则 e.setType(CROSS);//将e归类为“横跨边” else//否则 e.setType(FORWARD);//将e归类为“前向跨边” break; } }//至此,v的所有邻居都已访问结束,故 v.setFStamp(clock++); v.setStatus(VISITED);//将v标记为VISITED return null;//然后回溯 } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值