一、負進制數
將一個整數R進制分開,R爲負數。例如-15的-2進制如下:
程序輸入爲整數N和負整數R,輸出其R進制(-R<36)。大於10的數用A-Z表示。
// 負進制轉換,即R爲負數
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
int N, R; cin >> N >> R;
int n = N;
vector<char> res;
do{
int M = N%R;
if(M<0) M -= R, N += R;
char t = M+'0';
if(M>=10) t = M-10+'A';
res.push_back(t);
N /= R;
}while(N);
cout << n << "=";
for(int i = res.size()-1; i >= 0; i--) cout << res[i];
cout << "(base" << R << ")";
return 0;
}
二、有序全排列next_permutation
輸入數個數N和需要經過M次全排列,接着輸入這n個數,輸出M次全排列後的順序
// next_permutation的用法
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e4+10;
int a[maxn];
int main(int argc, char const *argv[])
{
int N, M; cin >> N >> M;
for(int i = 0; i < N; i++) cin >> a[i];
while(M--) next_permutation(a, a+N);
for(int i = 0; i < N; i++) cout << a[i] << " ";
return 0;
}
三、求連續自然數和
輸入一個數M,輸出M可以爲哪些連續整數求和得到,比如1998+1999+2000+2001+2002=10000,所以從1998到2002的一個自然數段爲M=10000的一個解。
輸入:
10000
輸出:
18 142
297 328
388 412
1998 2002
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6+10;
long long sum[maxn];
int main(int argc, char const *argv[])
{
int M; cin >> M;
for(int i = 1; i < maxn; i++) sum[i] = sum[i-1]+i;
for(int i = 0; i < maxn && i < M/2+1; i++){
long long key = M+sum[i];
int index = lower_bound(sum, sum+maxn, key)-sum;
while(sum[index]>key) index--;
if(sum[index]==key) cout << i+1 << " " << index << endl;
}
return 0;
}
四、求[1,n]這n個數有多少個約數
// 求[1,n]有多少個約數
// [1,n]是i的倍數的數有int(n/i)個,故暴力枚舉int(n/i),i從1-n,累加即可
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int n; cin >> n;
long long res = 0;
for(int i = 1; i <= n; i++){
res += (int)(n/i);
}
cout << res << endl;
return 0;
}
五、查詢區間[l,r]內素數個數
首先預處理[1,m]內素數,放在一個數組裏,每次查詢都可以用二分查。
// 區間查詢[l,r]內素數個數,可以篩出素數存在數組裏面然後用二分查,也可以用前綴和數組存儲表示1-i有多少個素數a[i]
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6+10;
int isPrime[maxn], prime[maxn];
int getPrime()
{
isPrime[1] = 1;
int index = 0;
for(int i = 2; i < maxn; i++)
{
if(isPrime[i]==0) prime[index++] = i;
for(int j = i+i; j < maxn; j+=i)
isPrime[j] = 1;
}
return index;
}
int main(int argc, char const *argv[])
{
int n, m; cin >> n >> m;
int num = getPrime();
while(n--)
{
int l, r; cin >> l >> r;
if(l<1 || r>m) cout << "Crossing the line" << endl;
else{
int begin = lower_bound(prime, prime+num, l)-prime;
int end = lower_bound(prime, prime+num, r)-prime;
if(prime[end]==r) end++;
cout << end-begin << endl;
}
}
return 0;
}
六、求有多少位,並求出其最後500位
位數爲,求其最後500爲需結合高精度和快速冪運算。
// 高精度和快速冪
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
vector<int> mul(vector<int> a, vector<int> b)
{
vector<int> c(1000);
for(int i = 0; i < 500; i++)
for(int j = 0; j < 500; j++)
c[i+j]+=a[i]*b[j];
for(int i = 0; i < 500; i++) c[i+1]+=c[i]/10, c[i]%=10;
return c;
}
int main()
{
int P; cin >> P;
int len = log10(2)*P+1;
cout << len << endl;
vector<int> a(1000, 0), b(1000, 0), res(1000, 0);
res[0] = 1, b[0] = 2;
while(P)
{
if(P%2==1) res = mul(res, b);
P /= 2;
b = mul(b, b);
}
for(int i = 499; i >= 0; i--) cout << res[i];
return 0;
}
七、快速冪
求的值
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
int a, b; cin >> a >> b;
int m=1025*1025, res = 1;
while(b)
{
if(b%2==1) res = (res*a)%m;
b /= 2;
a = (a*a)%m;
}
cout << res << endl;
return 0;
}
八、最大公約數gcd
求a和b的最大公約數
/*
歐幾里得算法:gcd(a,b)=gcd(b,a%b)
這個的證明就不再展開,因此程序遞歸到b爲0時終止,返回a即可
*/
#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
if(b==0) return a;
else return gcd(b, a%b);
}
int main(int argc, char const *argv[])
{
cout << gcd(49, 2100) << endl;
return 0;
}
九、求內有多少個質因子P
/*
求n!中有多少個質因子p?
方法一:n!=1*2*3*...*n,分別統計1到n中包含多少個質因子p,累加即可,時間複雜度爲O(nlogn)
方法二:n!有(n/p+n/(p^2)+n/(p^3)+...)個質因子p,時間複雜度爲O(logn)
note:n!後面有多少個0即爲求n!中質因子爲5的個數
*/
#include <bits/stdc++.h>
using namespace std;
//方法一
int cal(int n, int p)
{
int res = 0;
for (int i = 2; i <= n; ++i)
{
int temp = i;
while(temp%p==0)
{
res++;
temp /= p;
}
}
return res;
}
// 方法二
int cal2(int n, int p)
{
int res = 0;
while(n)
{
res += n/p;
n /= p;
}
return res;
}
int main(int argc, char const *argv[])
{
cout << cal(100000, 10) << endl;
cout << cal2(10, 5) << endl;
return 0;
}
十、質因子分解
/*
質因子分解是指將一個正整數n分解爲一個或者多個質數乘積的形式,例如6=2*3,180=2*2*2*3*5
對於n來說,如果存在[2,n]範圍內的質因子,則這些質因子全部小於等於sqrt(n);或者只存在一個大於sqrt(n)的質因子
因此只需要枚舉到sqrt(n)即可
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct factor
{
int x, cnt; // x爲質因子,cnt爲其個數
}fac[10];
int prime[maxn];
void set_prime()
{
for (int i = 2; i < maxn; ++i)
{
for (int j = i; j*i < maxn; ++j)
{
prime[j*i] = 1;
}
}
}
void slove(int n)
{
int num = 0;
for (int i = 2; i < sqrt(n+1); ++i)
{
if(prime[i]==0 && n%i==0)
{
fac[num].x = i;
fac[num].cnt = 0;
while(n%i==0)
{
fac[num].cnt++;
n /= i;
}
num++;
}
if(n==1) break; //及時退出循環
}
if(n!=1)
{
fac[num].x = n;
fac[num].cnt = 1;
}
}
int main(int argc, char const *argv[])
{
int n;
while(cin >> n)
{
slove(n);
for (int i = 0; i < 10; ++i)
{
if(fac[i].x==0) break;
cout << fac[i].x << ":" << fac[i].cnt << " ";
fac[i].x = fac[i].cnt = 0;
}
}
return 0;
}