k次方

本文介绍了一种处理大数运算的方法,特别关注于计算大数的快速幂运算,并通过实例演示了如何获取大数的前三位和后三位数字,适用于解决特定类型的大数问题。

链接:http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=16820&pid=1002

K次方

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)

Total Submission(s) : 25   Accepted Submission(s) : 12

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

所有在程式设计已经有点经验的人都知道,当k很大时你无法完整的表达出n k。例如: C语言的函数 pow(123456,455)能够用double资料型态来表达,但是你却无法得到所有正确的数字。然而,若是能知道一些最左边(leading)和最右边(trailing)数字的话,也可稍微得到一些满足。

Input

输入的第一行有一个整数TT < 1001),代表有几组测试资料。接下来的T行,每行有2个正整数nkn可以用32位元的整数表达,而k<10000001

Output

每组测试资料输出一行,输出LLL...TTT的样式。其中LLL代表n k的最左边3个数字,TTT代表n k的最右边3个数字。例如123456 2 = 15241383936,所以你应该输出152...936
你可以假设n k至少有6位数。

Sample Input

3

123456 1

123456 2

2100000056 67333

Sample Output

123...456

152...936

982...016

Author

shenlizhong

思路:这是一题典型的大数相乘的形式,直接套用函数公式肯定不行,题目要求输出前三位后三位,对于此有两步处理法

1·后三位,快速幂就可解决

2·前三位从100开始吧,一一枚举直达达到所求值为止,这里有个技巧,t所得结果的总为位数设h=100,一直进行h++,知道logh*1.0<=k*logn*1.0-(t-3)log(10.0))),为止,最终,将h--即可,(因为前面的循环多算了一个)

看代码:(参考了一下标程)

#include<stdio.h>

#include<math.h>

int pow_mod(int a,int b,int m)

{

if(b==0)

return 1;

int x=pow_mod(a,b/2,m);

__int64 ans=(__int64)x*x%m;

if(b%2==1)

ans=ans*a%m;

return (int)ans;

}

int main()

{

    int n,k;

    int a,b,t,h,i,j;

    while(scanf("%d",&n)!=EOF)

    {

    while(n--)

    {

    scanf("%d%d",&a,&b);

    k=(int)(b*log10(a*1.0)+1);//求位数 

    t=pow_mod(a%1000,b,1000);

    for(h=100;log(h*1.0)<=b*log(a*1.0)-(k-3)*log(10*1.0);h++);//以对数的形式求得前三位的数值!!!!!!(绝!!!!) 

    h--;

    printf("%3d...%03d\n",h,t);

    }

    }

return 0;

}

### C语言实现矩阵的K次方 为了高效地计算矩阵的K次幂,可以采用分治幂运算方法。该方法利用了分而治之的思想,通过将指数`k`分解为2的幂次来减少乘法次数,从而提高性能[^1]。 下面是一个完整的C语言程序示例,用于计算给定矩阵A的K次幂: #### 定义Matrix结构体 首先定义一个简单的二维矩阵结构体以及辅助函数来进行基本操作: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int size; double **data; } Matrix; // 初始化矩阵并分配内存 void init_matrix(Matrix *m, int size) { m->size = size; m->data = (double **)malloc(size * sizeof(double *)); for (int i = 0; i < size; ++i) m->data[i] = (double *)calloc(size, sizeof(double)); } // 复制矩阵 void copy_matrix(const Matrix *src, Matrix *dest) { dest->size = src->size; for (int i = 0; i < src->size; ++i) for (int j = 0; j < src->size; ++j) dest->data[i][j] = src->data[i][j]; } ``` #### 矩阵相乘函数 接着编写两个矩阵之间的乘法规则: ```c // 计算两个相同大小的矩阵相乘的结果存储到第三个参数中 void multiply_matrices(const Matrix *a, const Matrix *b, Matrix *res) { for (int row = 0; row < res->size; ++row) for (int col = 0; col < res->size; ++col) { res->data[row][col] = 0.0f; for (int k = 0; k < a->size; ++k) res->data[row][col] += a->data[row][k] * b->data[k][col]; } } ``` #### 分治幂运算法 最后是核心部分——递归形式的快速幂运算逻辑: ```c // 使用分治策略求解矩阵的k次幂 void power_divide_conquer(const Matrix *base, unsigned long exp, Matrix *result) { if (!exp) { // 当指数为零时返回单位矩阵 for (int i = 0; i < base->size; ++i) for (int j = 0; j < base->size; ++j) result->data[i][j] = (i == j ? 1 : 0); return; } if (exp & 1UL) { // 如果当前指数奇数,则先自乘再处理剩余偶数情况 power_divide_conquer(base, exp - 1, result); multiply_matrices(result, base, result); } else { // 否则直接对半拆分继续迭代直到最底层 power_divide_conquer(base, exp >> 1, result); multiply_matrices(result, result, result); } } ``` 以上就是整个过程的核心代码片段,在实际应用前还需要补充一些边界条件判断和错误处理机制以增强健壮性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值