P1786 帮贡排序
#include <bits/stdc++.h>
using namespace std;
int n;
struct node{
string name, state, xstate;//名字,职位,新职位
long long bg;//帮贡
int dj, h;//等级,序号
}b[115];
int cmp1(node x,node y){//帮贡相等按序号先
if(x.bg == y.bg) return x.h < y.h;
else return x.bg > y.bg;//帮贡大
}
int change(string a){
if (a=="BangZhu") return 0;
if (a=="FuBangZhu") return 1;
if (a=="HuFa") return 2;
if (a=="ZhangLao") return 3;
if (a=="TangZhu") return 4;
if (a=="JingYing") return 5;
if (a=="BangZhong") return 6;
}
int cmp2(node x, node y){//职位第一关键字,等级第二关键字
if(change(x.xstate) == change(y.xstate)){
if(x.dj == y.dj) return x.h < y.h;
return x.dj > y.dj;
}
return change(x.xstate) < change(y.xstate);
}
int main()
{
cin >> n;
for(int i=1; i<=n; i++){
cin >> b[i].name;
cin >> b[i].state;
cin >> b[i].bg;
cin >> b[i].dj;
b[i].h = i;//序号
}
sort(b+4, b+n+1, cmp1);//帮主副帮主不变
for(int i=1; i<=n; i++){//赋予新职位
if(i == 1)b[i].xstate = "BangZhu";
else if(i == 2||i == 3)b[i].xstate = "FuBangZhu";
else if(i == 4||i == 5)b[i].xstate = "HuFa";
else if(i > 5&&i <= 9)b[i].xstate = "ZhangLao";
else if(i > 9&&i <= 16)b[i].xstate = "TangZhu";
else if(i > 16&&i <= 41)b[i].xstate = "JingYing";
else b[i].xstate = "BangZhong";
}
sort(b+1, b+n+1, cmp2);
for(int i=1; i<=n; i++)
cout<<b[i].name<<" "<<b[i].xstate<<" "<<b[i].dj<<endl;
return 0;
}
P1591 阶乘数码
#include <bits/stdc++.h>
using namespace std;
int t;
int main()
{
cin >> t;
while(t--){
int n, a, m[3000];
int p = 1, jw, i, j;
cin >> n >> a;
memset(m, 0, sizeof(m));
m[1] = 1;
for(i=2; i<=n; i++){//求阶乘
jw = 0;
for(j=1; j<=p; j++){//高精*单精
m[j] = m[j]*i + jw;
jw = m[j] / 10;
m[j] %= 10;
}
while(jw > 0){
m[j] = jw % 10;
jw /= 10;
j++;
}
p = j - 1;
}
long long sum = 0;
for(i=p; i>=1; i--){
if(m[i] == a) sum++;
}
cout << sum << endl;
}
return 0;
}
P1249 最大乘积
1. 因数个数越多,乘积越大。
2. 用贪心从2开始递增累加ans直到<=n,把n-ans加到倒数第k个数,若无倒数k个数,加到2上
3. 用高精度累乘。
#include <bits/stdc++.h>
using namespace std;
int n, a[10010], used[10010];
int cheng(int n){//高精度*int
int len = a[0];
for(int i=1; i<=len; i++){
a[i] *= n;
}
for(int i=1; i<=len; i++){
a[i+1] += a[i] / 10;
a[i] %= 10;
}
while(a[len+1] > 9){
len++;
a[len+1] += a[len] / 10;
a[len] %= 10;
}
if(a[len+1]) len++;
return len;
}
int main()
{
cin >> n;
if(n == 3)cout << 1 << " " << 2 << endl << 2;
else if(n == 4)cout << 1 << " " << 3 << endl << 3;
else{
int k = n, id;
for(int i=2; i<=n; i++){
k -= i;
used[i] = 1;
if(k < 0){
id = i;//加到了i前一个数
used[i] = 0;
k += i;
if(k==0) id = i-1;
break;
}
}
//处理余数k
if(k > id - 2){//没有k个数
used[2] = 0;
used[2+k] = 1;
id = 2 + k;
}else{
used[id-k] = 0;
used[id] = 1;
}
a[0] = 1, a[1] = 1;//a[0]表示位数
for(int i=2; i<=id; i++){
if(used[i]){
cout << i << " ";
a[0] = cheng(i);//返回乘结果位数
}
}
cout << endl;
//高精乘打印结果
for(int i=a[0]; i>=1; i--)
cout << a[i];
cout << endl;
}
return 0;
}
P1045 [NOIP2003 普及组] 麦森数
高精+快速幂
一、求位数
2^p 与 2^p-1 位数相同,且10^n位数 = n+1;
因此2^p = 10^(log10(2)*p),所以位数 = log10(2)*p+1(C++中cmath库自带log10()函数)
二、求后500位
快速幂模板:乘法部分换成高精乘
快速幂的关键就是我们如何把b分解为2的幂之和,原理:快速幂算法(C++)_L-M-Y的博客-CSDN博客_快速幂c++代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mypow(ll a, ll b){//a^b 快速幂模板
ll ans = 1;
while(b){
if(b%2 == 1)ans *= a;
b /= 2;
a *= a;
}
return ans;
}
int main()
{
cout << mypow(2, 10);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int p, sav[1005], res[1005], f[1005];//乘法开两倍长度
void fun1(){
memset(sav, 0, sizeof(sav));
for(int i=1; i<=500; i++)
for(int j=1; j<=500; j++)
sav[i+j-1] += res[i]*f[j];
for(int i=1; i<=500; i++){
sav[i+1] += sav[i] / 10;
sav[i] %= 10;
}
memcpy(res, sav, sizeof(res));
}
void fun2(){
memset(sav, 0, sizeof(sav));
for(int i=1; i<=500; i++)
for(int j=1; j<=500; j++)
sav[i+j-1] += f[i]*f[j];
for(int i=1; i<=500; i++){
sav[i+1] += sav[i] / 10;
sav[i] %= 10;
}
memcpy(f, sav, sizeof(f));
}
int main()
{
cin >> p;
cout << (int)(log10(2)*p+1) << endl;//位数
res[1] = 1;
f[1] = 2;
while(p != 0){//快速幂模板
if(p & 1) fun1();//二进制位对应1,高精乘
p >>= 1;//相当于p/2
fun2();
}
res[1] -= 1; // 最终求 2^p - 1,所以最后一位 -= 1
for(int i=500; i>=1; i--){
if(i!=500 && i%50==0)
cout << endl << res[i];
else cout << res[i];
}
return 0;
}
试题 算法训练 A的B的C次方次方
由费马小定理: a^(b^c) % p = a^[b^c % (p-1)] % p
pow(a, (b, c, p-1), p);
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a, b, c;
ll mypow(ll a, ll b, ll p){
ll ans = 1;
while(b){
if(b & 1)ans = ans*a%p;
b >>= 1;
a = a*a%p;
}
return ans;
}
int main()
{
cin >> a >> b >> c;
ll p = 1000000007;
cout << mypow(a, mypow(b, c, p-1), p);
return 0;
}