day 12 模拟和高精度

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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值