# include
using namespace std;
const int N = 100010;
int q[N];
void quick_sort(int q[], int l, int r)
{
if(l>=r) return;
int i=l-1,j=r+1,temp=q[l];
while(i<j)
{
do i++;while(q[i]<temp);
do j--;while(q[j]>temp);
if(i<j)
swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j+1, r);
}
int main()
{
int n;
scanf("%d", &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++)
printf("%d ", q[i]);
return 0;
}
从无序列数组中找有序的第k个数,其实改一下输出就可以了
# include
using namespace std;
const int N = 100010;
int q[N];
void quick_sort(int q[], int l, int r)
{
if(l>=r) return;
int i=l-1,j=r+1,temp=q[l];
while(i<j)
{
do i++;while(q[i]<temp);
do j--;while(q[j]>temp);
if(i<j)
swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j+1, r);
}
int main()
{
int n;
int x;
scanf("%d", &n);
scanf("%d", &x);
for(int i=0;i<n;i++)
scanf("%d", &q[i]);
quick_sort(q, 0, n-1);
printf("%d", q[x-1]);
return 0;
}
核心:分治-》双指针问题
#include
using namespace std;
const int N = 100010;
void merge_sort(int q[], int l, int r)
{
int temp[N]; //辅助数组
if(l>=r) return;
int mid=(l+r)>>1; //取中间值作为分界点
//递归排序左右
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]) temp[k++]=q[i++];
else temp[k++]=q[j++];
}
//当一只先用完,另一只直接挂在temp数组后
while(i<=mid) temp[k++]=q[i++];
while(j<=r) temp[k++]=q[j++];
//将结果从辅助数组转移到原数组
for(int i=l,j=0; i<=r; i++,j++)
q[i]=temp[j];
}
int q[N];
int main()
{
int n;
scanf("%d", &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;
}
cpp没有内置很大的数,很大的数在cpp里是以数组形式存储,所以大数运算需要定义
加法:
#include
#include
using namespace std;
const int N = 1e6+10;
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]; //t=t+A[i]+B[i]
C.push_back(t%10); //对t取整
t /= 10;//求向高位的进位
}
if(t!=0) C.push_back(1); //超过位数有进位高位需要补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'); //注意a是string类型,转成int要减去‘0’
for(int j=b.size()-1; j>=0; j--) B.push_back(b[j]-'0');
//auto 编译器会自动判断C的类型
auto C = add(A, B);
for(int i=C.size()-1;i>=0;i--) printf("%d", C[i]);
return 0;
}
减法
#include
#include
using namespace std;
const int N = 1e6+10;
//比较两数大小
bool cmp(vector<int>&A, vector<int>&B)
{
if(A.size()>B.size()) return A.size()>B.size(); //位数多的大
for(int i=A.size()-1; i>=0; i--) //位数相同
{
if(A[i]!=B[i]) //同位的数谁大谁就大
return A[i]>B[i];
}
return true; //相等返回true
}
vector<int> sub(vector<int>&A, vector<int>&B) //A一定要比B大哈
{
vector<int>C; //定义返回值
for(int i=0,t=0 ;i<A.size(); i++)
{
t = A[i] - t; //看低位是否产生借位
if(i<B.size())
t = t- B[i]; //t = A-B-t
C.push_back((t+10)%10); //如果t小于0要借位+10
if(t<0) t=1; //看是否向高位借位
else t=0;
}
//去除高位的0
while(C.size()>1&&C.back()==0)
C.pop_back();
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'); //注意a是string类型,转成int要减去‘0’
for(int j=b.size()-1; j>=0; j--) B.push_back(b[j]-'0');
if(cmp(A, B))
{
auto C = sub(A, B);
for(int i=C.size()-1;i>=0;i--) printf("%d", C[i]);
}
else
{
auto C = sub(B, A);
printf("-");
for(int i=C.size()-1;i>=0;i--) printf("%d", C[i]);
}
return 0;
}
输入一个长度为 n的整数序列。
接下来再输入 m 个询问,每个询问输入一对 l,r。
对于每个询问,输出原序列中从第 l个数到第 r个数的和。
#include
using namespace std;
const int N = 100010;
int n, m;
int a[N], s[N];
int main()
{
scanf("%d", &n);
scanf("%d", &m); //询问次数
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
//构造出前缀和序列
for(int i=1; i<=n; i++) s[i]=s[i-1]+a[i];
while(m--)//m次询问
{
int l,r;
scanf("%d", &l);
scanf("%d", &r);
printf("%d\n", s[r]-s[l-1]); //求出特定子区间的和
}
return 0;
}