首页 > 代码库 > [Gauss]POJ2065 SETI
[Gauss]POJ2065 SETI
题意: *代表0,a-z代表1-26
题目第三行给了一个公式 f (k) = ∑0<=i<=n-1aiki (mod p) {f(i)是输入的一串字符串中第i的字母代表的数 ai即xi是要求的 p是输入给的}
然后列出len个方程 用Gauss求解就好了
这题保证有唯一解 因此不必考虑无解或自由未知量
1 int mod; 2 LL quick(LL a, LL b) 3 { 4 LL ans=1; 5 while(b) 6 { 7 if(b & 1)ans=(ans*a)%mod; 8 a=(a*a)%mod; 9 b>>=1; 10 } 11 return ans%mod; 12 } 13 int gcd(int a, int b) 14 { 15 return b==0? a:gcd(b, a%b); 16 } 17 int lcm(int a, int b) 18 { 19 return a/gcd(a, b)*b; 20 } 21 void ex_gcd(int a, int b, int &x, int &y) 22 { 23 if(b) 24 { 25 ex_gcd(b, a%b, x, y); 26 int tmp=x; 27 x=y; 28 y=tmp-(a/b)*y; 29 } 30 else 31 { 32 x=1, y=0; 33 return ; 34 } 35 } 36 37 int a[300][300]; // 增广矩阵 38 int x[300]; // 解 39 int free_x[300]; // 标记是否为自由未知量 40 41 void Gauss(int n, int m) // n个方程 m个未知数 即 n行m+1列 42 { 43 //转换为阶梯形式 44 int col=0, k, num=0; 45 for(k=0; k<n && col<m; k++, col++) 46 { 47 //枚举行 48 int max_r=k; 49 for(int i=k+1; i<n; i++) //找到第col列元素绝对值最大的那行与第k行交换 50 if(abs(a[i][col])>abs(a[max_r][col])) 51 max_r=i; 52 if(max_r!=k)// 与第k行交换 53 for(int j=col; j<m+1; j++) 54 swap(a[k][j], a[max_r][j]); 55 if(!a[k][col])// 说明该col列第k行以下全是0了 56 { 57 k--; 58 free_x[num++]=col; 59 continue; 60 } 61 for(int i=k+1; i<n; i++) // 枚举要删除的行 62 if(a[i][col]) 63 { 64 int LCM=lcm(abs(a[i][col]), abs(a[k][col])); 65 int ta=LCM/abs(a[i][col]); 66 int tb=LCM/abs(a[k][col]); 67 if(a[i][col]*a[k][col]<0) 68 tb=-tb; 69 for(int j=col; j<m+1; j++) 70 a[i][j]=((a[i][j]*ta-a[k][j]*tb)%mod+mod)%mod; 71 } 72 } 73 74 for(int i=k; i<n; i++) 75 if(a[i][col]) 76 return ; // 无解 77 78 if(k<m) //m-k为自由未知量个数 79 return ; 80 81 // 唯一解 回代 82 for(int i=m-1; i>=0; i--) 83 { 84 int tmp=a[i][m]; 85 for(int j=i+1; j<m; j++) 86 { 87 if(a[i][j]) 88 tmp-=a[i][j]*x[j]; 89 tmp=(tmp%mod+mod)%mod; 90 } 91 int xx, yy; 92 ex_gcd(a[i][i], mod, xx, yy); 93 xx=(xx%mod+mod)%mod; 94 x[i]=(tmp*xx)%mod; 95 } 96 return ; 97 } 98 99 void init()100 {101 memset(a, 0, sizeof(a));102 memset(x, 0, sizeof(x));103 }104 105 char s[105];106 int main()107 {108 int T;109 while(~scanf("%d", &T))110 while(T--)111 {112 init();113 scanf("%d%s", &mod, s);114 int n=strlen(s);115 for(int i=0; i<n; i++)116 {117 a[i][n]=(s[i]==‘*‘? 0:s[i]-‘a‘+1);118 for(int j=0; j<n; j++)119 a[i][j]=quick(i+1, j);120 }121 Gauss(n, n);122 for(int i=0; i<n; i++)123 {124 printf("%d", x[i]);125 if(i==n-1)126 printf("\n");127 else128 printf(" ");129 }130 }131 return 0;132 }
[Gauss]POJ2065 SETI
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。