题目地址:POJ 2065
题意:输入一个素数p和一个字符串s(只包含小写字母和‘*’),字符串中每个字符对应一个数字,‘*‘对应0,‘a’对应1,‘b’对应2....
eg:str[] = "abc", 那么说明 n=3, 字符串所对应的数列为1, 2, 3。
同时题目定义了一个函数:a0*1^0 + a1*1^1+a2*1^2+........+an-1*1^(n-1) = f(1)(mod p), f(1) = str[0] = a = 1;
a0*2^0 + a1*2^1+a2*2^2+........+an-1*2^(n-1) = f(2)(mod p), f(2) = str[1] = b = 2;
..........
a0*n^0 + a1*n^1+a2*n^2+........+an-1*n^(n-1) = f(n)(mod p),f(n) = str[n-1] = ````
求出 a0,a1,a2....an-1。
思路:和POJ 2947很相像,只不过这道题的解是唯一确定的,也就是不需要判断无解和无穷解的情况,同时求i^(n-1)的时候用快速幂取余做,pow会溢出。
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> #include <algorithm> #include <set> #include <queue> #include <stack> #include <map> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const double pi= acos(-1.0); const double esp=1e-6; const int MAXN=110; int aug[MAXN][MAXN]; int x[MAXN]; int m,n; int gcd(int a,int b) { int r; while(b!=0){ r=b; b=a%b; a=r; } return a; } int lcm(int a,int b) { return a/gcd(a,b)*b; } int Gauss(int mod) { int i,j; int LCM; int ta,tb; int row,col,max_r; int tmp; for(row=0,col=0;row<m&&col<n;row++,col++){ max_r=row; for(i=row+1;i<m;i++){ if(abs(aug[i][col])>abs(aug[max_r][col])) max_r=i; } if(max_r!=row){ for(j=row;j<n+1;j++) swap(aug[row][j],aug[max_r][j]); } if(aug[row][col]==0){ row--; continue; } for(i=row+1;i<m;i++){ if(aug[i][col]!=0){ LCM=lcm(aug[i][col],aug[row][col]); ta=LCM/abs(aug[i][col]); tb=LCM/abs(aug[row][col]); if(aug[i][col]*aug[row][col]<0) tb=-tb; for(j=col;j<n+1;j++){ aug[i][j]=((aug[i][j]*ta-aug[row][j]*tb)%mod+mod)%mod; } } } } for(i=n-1;i>=0;i--){ tmp=aug[i][n]; for(j=i+1;j<n;j++){ if(aug[i][j]!=0) tmp-=aug[i][j]*x[j]; tmp=(tmp%mod+mod)%mod; } while(tmp%aug[i][i]!=0) tmp+=mod; x[i]=(tmp/aug[i][i])%mod; } return 0; } int pow_mod(int a,int n,int mod) { int ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=(a*a)%mod; n>>=1; } return ans; } int main() { int T,p,i,j; char str[MAXN]; scanf("%d",&T); while(T--){ scanf("%d %s",&p,str); n=m=0; int len=strlen(str); for(i=0;i<len;i++){ if(str[i]=='*') aug[i][len]=0; else aug[i][len]=str[i]-'a'+1; for(j=0;j<len;j++) aug[i][j]=pow_mod(i+1,j,p); } n=m=len; Gauss(p); for(i=0;i<len-1;i++) printf("%d ",x[i]); printf("%d\n",x[i]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013486414/article/details/47005013