文章目录
写在前面
代码模版
bool isryear(int n){
return n%400==0||(n%4==0&&n%100!=0);
}
代码模板
//也可以将数组第一个位置空出来,即填上一个随意的值,这样就可以将月份和数组下标对应了,方便访问
int pmonths[]={31,28,31,30,31,30,31,31,30,31,30,31}; //平年每月天数
int rmonths[]={31,29,31,30,31,30,31,31,30,31,30,31}; //闰年每年天数
一维前缀和
预处理出s[],s[i]存储前i个数的和
s[i]=a[1]+a[2]+...+a[i]
计算[l,r]区间和=s[r]-s[l-1]
二维前缀和
左上角坐标为(1,1),右下角坐标为(i,j)的前缀和(区域内所有数的和)
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]
求左上角坐标为(x1,y1),右下角坐标为(x2,y2)的前缀和
s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]
一维差分
int b[N]; //b为差分数组,直接定义为全局即可,如果要对某个数组进行差分操作,直接先将该数组中每个数进行insert(i,i,a[i])操作即可得到a的差分数组b
//对区间[l,r]进行差分操作时
void insert(int l,int r,int c){
b[l]+=c;
b[r+1]-=c;
}
//差分完后对b数组求前缀和即可,求完前缀和后的b数组即进行完对某些区间加减某个数操作后的原数组
二维差分
int b[N][N]; //差分数组
//对左上角坐标为(l1,r1),右下角坐标为(l2,r2)的矩阵进行差分操作时
void insert(int l1,int r1,int l2,int r2,int c){
b[l1][r1]+=c;
b[l1][r2+1]-=c;
b[l2+1][r1]-=c;
b[l2+1][r2+1]+=c;
}
//同样,差分操作完成后对b数组求前缀和,即可得到对原数组某些区域加减某个数后操作的原数组
//首先确定区间的二段性:二部分分别满足不同的性质。以任意一部分的性质作为check条件,如果mid满足check判断区间应该缩小到哪部分,如果在[l,mid]利用模板1,如果在[mid,r]利用模板2
//模版1
int l=0,r=n; //二分区间[l,r]
while(l<r){
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
//模版2
int l=0,r=n; //二分区间[l,r]
while(l<r){
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
//算法结束l=r,l、r均为结果
代码模板
int p[N]; //祖宗结点数组
for(int i=1;i<=n;i++) p[i]=i; //初始化
int find(int x){ //查找祖宗结点
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
p[find(a)]=find(b); //合并a,b集合
代码模板
bool isprimes(int n){
if(n<2) return false;
for(int i=2;i<=n/i;i++){
if(n%i==0) return false;
}
return true;
}
代码模板
bool st[N]; //存储每个数是否被筛掉
int primes[N],cnt; //primes[]存储每个质数,cnt记录质数的数量
void getprimes(int n){
st[0]=st[1]=true;
for(int i=2;i<=n;i++){
if(!st[i]){
primes[cnt++]=i;
for(int j=i+i;j<=n;j+=i){
st[j]=true;
}
}
}
}
A~Z字母即可)//传入为string类型
int ntoten(string s,int n){ //n表示传入的是多少进制数,s为n进制数
int ans=0;
for(int i=0;i<s.size();i++){
ans=ans*n+s[i]-'0';
}
return ans;
}
//传入为数组,num为数组中元素个数
int ntoten(int a[],int num,int n){
int ans=0;
for(int i=0;i<num;i++){
ans=ans*n+a[i];
}
}
A~Z即可)//利用栈
void tenton(int nums,int n){ //nums为需要转换的数,n为需要转换的进制数
stack<int> s;
while(nums){
s.push(nums%n);
nums/=n;
}
while(!s.empty()){
cout<<s.top();
s.pop();
}
}
//用数组存储,然后反转数组
int a[N];
void tenton(int nums,int n){ //nums为需要转换的数,n为需要转换的进制数
int cnt=0; //记录数组中元素个数
while(nums){
a[cnt++]=nums%n;
nums/=n;
}
reverse(a,a+cnt);
for(int i=0;i<cnt;i++) cout<<a[i];
}
#include <iomanip>,利用fixed和setprecision()来实现四舍五入保留任意位数小数。代码模板
//例:对a保留两位小数
cout<<fixed<<setprecision(2)<<a;
a与b的最大公约数等于b与a%b的最大公约数。代码模版
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
a与b的最大公约数与最小公倍数的乘积=a * b,所以最小公倍数=a*b/gcd(a,b)代码模板
typedef long long LL; //需要快速幂的值一般较大,所以开long long
//返回a^b%p的结果
int qmi(int a,int b,int p){
LL res=1%p;
while(b){
if(b&1) res=res*a%p;
b>>=1;
a=(LL)a*a%p;
}
return res;
}
#include <string> //头文件
size() //返回大小
empty() //判断是否为空
clear() //清空
substr(起始下标,子串长度) //返回指定长度子串
find() //查找字符第一次出现的位置,如果没有出现过则返回string::npos
//非成员函数
stoi() //将字符串转化成int类型,传入string类型字符串
atoi() //将字符串转化为int类型,传入char类型字符串
#include <vector> //头文件
size() //返回元素个数
empty() //判空
clear() //清空
push_back() //在尾部添加一个元素
pop_back() //删除最后一个元素
begin()/end() //首迭代、尾迭代
front()/back() //返回第一个/最后一个元素
注:还有deque,由于本人不怎么使用没有总结,感兴趣的朋友有时间了解一下。
#include <queue> //头文件
//queue
size() //返回队列中元素的个数
empty() //判空
push() //在末尾加入一个元素
pop() //删除第一个元素
front()/back() //返回第一个/最后一个元素
//priority_queue
size() //返回优先队列中元素的个数
empty() //判空
push() //加入一个元素
pop() //删除堆顶元素
top() //返回堆顶元素
默认定义为大根堆
//定义成小根堆方法:
priority_queue<int,vector<int>,greater<int>> q;
#include <stack> //头文件
size() //返回栈元素个数
empty() //判空
push() //入栈
pop() //出栈
top() //返回栈顶元素
#include <set> //头文件
set去重,multiset不去重,均默认升序排序
底层红黑树
size() //返回集合中元素个数
empty() //判空
clear() //清空所有元素
insert() //在集合中插入元素
find() //查找一个数,如果找到则返回该数第一次出现位置的迭代器,否则返回尾迭代
count() //返回某个值元素的个数
#include <map> //头文件
map去重,multimap不去重,均默认以key值(第一属性)升序排序
底层红黑树
size() //返回map中元素个数
empty() //判空
insert() //插入元素
find() //同上
count() //同上
#include <unordered_set> //头文件
#include <unordered_map>
底层哈希
操作与set、map基本一致,参考上面即可
#include <utility> //头文件
first //第一个元素
second //第二个元素
//适用sort对其排序时默认以第一个元素升序排序
#include <algorithm> //头文件
sort() //传入首、尾地址(或首、尾迭代)排序,默认升序
//若要降序排序或对结构体按其属性排序,需手写cmp函数
bool cmp(int a,int b){
return a>b;
}
sort(a,a+n,cmp);
//对结构体指定属性排序,例:
struct Student{
string name;
double score;
}stu[N];
bool cmp(Student A,Student B){
return A.score>B.score;
}
//按成绩降序排序
sort(stu,stu+n,cmp);
max() //取最大值
min() //取最小值
swap() //交换两个元素的值
reverse() //传参和sort一致,反转区间内的元素顺序
unqiue() //传参和和sort一致,去重相邻的相同元素,若原序列无序首先需排序,返回去重后原序列尾迭代
Dijkstra算法:求解边权均为正的单源最短路。
朴素版本:适用于稠密图(边数和点数平方一个数量级)
代码模板
int n; //点数
int g[N][N]; //邻接矩阵存储图
int dist[N]; //存储每个点到1号点的最短距离
bool st[N]; //存储每个点的最短路是否已经确定
int dijkstra(){
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++){ //迭代n次
int t=-1;
for(int j=1;j<=n;j++){ //寻找距离最小的点
if(!st[j]&&(t==-1||dist[t]>dist[j])) t=j;
}
st[t]=true; //标记为已确定
for(int j=1;j<=n;j++) dist[j]=min(dist[j],dist[t]+g[t][j]); //用距离最小的点来更新其他点距离1号点的距离
}
if(dist[n]==0x3f3f3f3f) return -3; //最短路不存在
else return dist[n]; //存在直接返回
}
选看:
堆优化Dijkstra算法:适用于稀疏图(边数和点数一个数量级)可以参考我的该篇博客
代码模板
int n,m; //n表示点数,m表示边数
int h[N],e[M],ne[M],w[M],idx; //邻接表存储图
int dist[N]; //存储每个点到1号点的最短距离
bool st[N]; //存储每个点是否已经在队列中
//邻接表加边
void add(int a,int b,int c){
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
int spfa(){
memset(dist,0x3f,sizeof dist);
queue<int> q;
dist[1]=0;
st[1]=true;
q.push(1);
while(!q.empty()){
int t=q.front();
q.pop();
st[t]=false;
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>dist[t]+w[i]){
dist[j]=dist[t]+w[i];
if(!st[j]){
st[j]=true;
q.push(j);
}
}
}
}
if(dist[n]==0x3f3f3f3f) return -3;
else return dist[n];
}
注:若时间紧迫,优先记忆Floyd算法,也可解决单源最短路问题,只不过时间复杂度较高,可以用其获得部分分数。
代码模板
int n; //点数
int d[N][N]; //邻接矩阵存储图,算法结束后d[i][j]存储i、j之间的最短路径长度
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) d[i][j]=0;
else d[i][j]=0x3f3f3f3f;
}
}
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
}
}
}
//注意,若图中存在负权边,所以1号点无法到n号点,d[1][n]也可能被更新也可能则d[i][j]若大于0x3f3f3f3f/2即可认为最短路不存在
代码模板
int n; //点数
int dist[N]; //存储点到当前最小生成树的距离
int g[N][N]; //邻接矩阵存储每条边
bool st[N]; //存储每个点是否已经在生成树中
int prim(){
memset(dist,0x3f,sizeof dist);
int res=0; //存储最小生成树边权重之和
for(int i=0;i<n;i++){
int t=-1;
for(int j=1;j<=n;j++){ //寻找距离当前生成树最小的点
if(!st[j]&&(t==-1||dist[t]>dist[j])) t=j;
}
if(i&&dist[t]==0x3f3f3f3f3) return 0x3f3f3f3f; //如果距离最小的点的距离仍然是正无穷说明无最小生成树
if(i) res+=dist[t];
for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]);
st[t]=true;
}
return res; //返回最小生成树边权重之和即可
}
代码模板
int p[N]; //并查集父结点数组
int find(int x){ //并查集find操作
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
struct Edge{ //存储每条边
int a,b,w;
}edges[M];
bool cmp(Edge A,Edge B){ //手写cmp,使sort能为结构体排序
return A.w<B.w;
}
int kruskal(){
for(int i=1;i<=n;i++) p[i]=i; //初始化并查集
sort(edges,edges+m,cmp); //按边权从小到大排序
int res=0,cnt=0; //res记录最小生成树边权之和,cnt记录当前最小生成树种的边数
for(int i=0;i<m;i++){
int a=edges[i].a,b=edges[i].b,w=edges[i].w;
if(find(a)!=find(b)){ //最小边权的起点和终点a,b不在一个连通块则合并他们
p[find(b)]=find(a);
res+=w;
cnt++;
}
}
if(cnt<n-1) return 0x3f3f3f3f; //n个点,最小生成树的边应为n-1条,少于n-1说明没有最小生成树
else return res;
}
代码模板
int dp[N]; //存储每个状态的最大价值
int v[N],w[N]; //v[]存储每个物品的体积,w[]存储每个物品的价值
int n,m; //n为物品数,m为背包容积
for(int i=1;i<=n;i++){ //枚举每个物品
for(int j=m;j>=v[i];j--){ //逆序枚举背包体积
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
代码模板
int dp[N]; //存储每个状态的最大价值
int v[N],w[N]; //v[]存储每个物品的体积,w[]存储每个物品的价值
int n,m; //n为物品数,m为背包容积
for(int i=1;i<=n;i++){ //枚举每个物品
for(int j=v[i];j<=m;j++){ //正序枚举背包体积
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
代码模板
int dp[N]; //存储每个状态的最大价值
int v[N],w[N],s[N]; //v[]存储每个物品的体积,w[]存储每个物品的价值,s[]存储每个物品的最大数量
int n,m; //n为物品数,m为背包容积
for(int i=1;i<=n;i++){ //枚举每个物品
for(int j=m;j>=v[i];j--){ //逆序枚举背包体积
for(int k=0;k<=s[i]&&k*v[i]<=j;k++){
dp[j]=max(dp[j],dp[j-k*v[i]]+k*w[i]);
}
}
}
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g
打印1:defsum(i)i=i+[2]end$x=[1]sum($x)print$x打印12:defsum(i)i.push(2)end$x=[1]sum($x)print$x后者是修改全局变量$x。为什么它在第二个例子中被修改而不是在第一个例子中?类Array的任何方法(不仅是push)都会发生这种情况吗? 最佳答案 变量范围在这里无关紧要。在第一段代码中,您仅使用赋值运算符=为变量i赋值,而在第二段代码中,您正在修改$x(也称为i)使用破坏性方法push。赋值从不修改任何对象。它只是提供一个名称来引用一个对象。方法要么是破坏性