POJ 2065 SETI (高斯消元 取模)

题目链接

题意:

输入一个素数p和一个字符串s(只包含小写字母和‘*’),字符串中每个字符对应一个数字,‘*‘对应0,‘a’对应1,‘b’对应2....

例如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.

感谢大神翻译。

分析:

除了题意有点难懂以外,没有什么,就是给了一个一个含有n个方程n个未知数的线性方程组,让求解。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <algorithm>
  7 #define LL __int64
  8 const int maxn = 70+10;
  9 const int INF = 1<<28;
 10 using namespace std;
 11 int equ, var, fn;
 12 int a[maxn][maxn], x[maxn];
 13 bool free_x[maxn];
 14
 15 int gcd(int a, int b)
 16 {
 17     return b==0?a:gcd(b, a%b);
 18 }
 19 int lcm(int a, int b)
 20 {
 21     return a*b/gcd(a, b);
 22 }
 23 int Gauss(int x_mo)
 24 {
 25     //int x_mo;
 26     //x_mo = 7;
 27     int i, j, k, max_r, col;
 28     int ta, tb, LCM, tmp, fx_num;
 29     int free_index;
 30     col = 0;
 31
 32     for(k = 0; k<equ && col<var; k++, col++)
 33     {
 34         max_r = k;
 35         for(i = k+1; i < equ; i++)
 36             if(abs(a[i][col])>abs(a[max_r][col]))
 37                 max_r = i;
 38
 39         if(max_r != k)
 40             for(j = k; j < var+1; j++)
 41                 swap(a[k][j], a[max_r][j]);
 42
 43         if(a[k][col]==0)
 44         {
 45             k--;
 46             continue;
 47         }
 48         for(i = k+1; i < equ; i++)
 49         {
 50             if(a[i][col] != 0)
 51             {
 52                 LCM = lcm(abs(a[i][col]), abs(a[k][col]));
 53                 ta = LCM/abs(a[i][col]);
 54                 tb= LCM/abs(a[k][col]);
 55                 if(a[i][col]*a[k][col] < 0) tb = -tb;
 56
 57                 for(j = col; j < var+1; j++)
 58                     a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%x_mo+x_mo)%x_mo;
 59             }
 60         }
 61     }
 62     for(i = var-1; i >= 0; i--)
 63     {
 64         tmp = a[i][var];
 65         for(j = i+1; j < var; j++)
 66             if(a[i][j] != 0)
 67                 tmp = ((tmp-a[i][j]*x[j])%x_mo+x_mo)%x_mo;
 68
 69         if(a[i][i]==0)
 70             x[i] = 0;
 71         else
 72         {
 73             //if(tmp%a[i][i] != 0) return -2;
 74             while(tmp%a[i][i]!=0) tmp += x_mo;
 75             x[i] = (tmp/a[i][i])%x_mo;
 76         }
 77     }
 78     return 0;
 79 }
 80 int check(char ch)
 81 {
 82     if(ch==‘*‘) return 0;
 83     return ch-‘a‘+1;
 84 }
 85 int Pow(int tmp, int j, int x_mo)
 86 {
 87     int sum = 1;
 88     tmp %= x_mo;
 89     for(int i = 1; i <= j; i++)
 90     {
 91         sum *= tmp;
 92         sum %= x_mo;
 93     }
 94     return sum%x_mo;
 95 }
 96 int main()
 97 {
 98     int x_mo, i, j, t, len, n;
 99     char s[maxn];
100     scanf("%d", &t);
101     while(t--)
102     {
103         scanf("%d %s", &x_mo, s);
104         len = strlen(s);
105         n = len;
106         equ = n; var = n;
107         memset(a, 0, sizeof(a));
108         memset(x, 0, sizeof(x));
109         for(i = 0; i < n; i++)
110         a[i][n] = (check(s[i]))%x_mo; //按照题目要求
111         for(i = 0; i < n; i++)
112         {
113             int tmp = check(s[i]);
114             for(j = 0; j < n; j++)
115             {
116               a[i][j] = Pow(i+1, j, x_mo); //按照题目要求,由于直接求(i+1)^j会超int所以在计算的时候一直取模
117             }
118         }
119         fn = Gauss(x_mo);
120         for(i = 0; i < n; i++)
121         {
122             if(i == n-1) printf("%d\n", x[i]);
123             else  printf("%d ", x[i]);
124         }
125     }
126     return 0;
127 }

POJ 2065 SETI (高斯消元 取模),布布扣,bubuko.com

时间: 2024-10-12 12:10:27

POJ 2065 SETI (高斯消元 取模)的相关文章

POJ.2065.SETI(高斯消元 模线性方程组)

题目链接 http://blog.csdn.net/Clove_unique/article/details/54381675 http://blog.csdn.net/u013081425/article/details/24299047 http://blog.csdn.net/lin375691011/article/details/38406737 https://www.cnblogs.com/IMGavin/p/5933037.html /* 模意义下的高斯消元,在初等行变换时把k=

Poj 2065 SETI (高斯消元)

题目连接: http://poj.org/problem?id=2065 题目描述: 给出和明码长度相同的暗码,暗码的每一个字母f(k)都是由明码ai按照 f (k) = ∑0<=i<=n-1a i *ki(mod p) 转化而来 ,已知暗码,求出明码? 解题思路: 使用高斯消元,重要的就是模型转化,列出来增广矩阵题目就距离AC不远了.这个题目的增广矩阵为: a0*1^0 + a1*1^1 + a2*1^2 + ........ + an*1^n = f(1)(mod p); a0*2^0 +

POJ 2065 SETI 高斯消元解线性同余方程

题意: 给出mod的大小,以及一个不大于70长度的字符串.每个字符代表一个数字,且为矩阵的增广列.系数矩阵如下 1^0 * a0 + 1^1 * a1 + ... + 1^(n-1) * an-1 = f(1) 2^0 * a0 + 2^1 * a1 + ... + 2^(n-1) * an-1   = f(2) ........ n^0 * a0 + n^1 * a1 + ... + n^(n-1) * an-1  = f(n) 快速幂取模下系数矩阵 #include <cstdio> #i

2017湘潭赛 A题 Determinant (高斯消元取模)

链接 http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1260 今年湘潭的A题 题意不难 大意是把n*(n+1)矩阵去掉某一列 求去掉那一列之后的对应的行列式的值 mod 1e9+7 思路1  : 先做一次高斯消元 得到一个阶梯矩阵  只有最后两列没有被消元 然后每去掉一列 拿出新的矩阵  做一次消元 1      a12   a13   a14 0       1      a23   a24 0        0  

POJ 1830 【高斯消元第一题】

首先...使用abs()等数学函数的时候,浮点数用#include<cmath>,其它用#include<cstdlib>. 概念: [矩阵的秩] 在线性代数中,一个矩阵A的列秩是A的线性无关的纵列的极大数目.类似地,行秩是A的线性无关的横行的极大数目. 此题如果有解,解的个数便是2^(自由变元个数),因为每个变元都有两种选择,既1 << n 对于r以下的行,必定全是0,那么如果a[i][n]!=0 必然出现矛盾,于是判定无解. 1 #include <iostr

Poj 1830 高斯消元

开关问题 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5418 Accepted: 2022 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任意一个开关,最多只能进行一次开关操作.你的任

POJ SETI 高斯消元 + 费马小定理

http://poj.org/problem?id=2065 题目是要求 如果str[i] = '*'那就是等于0 求这n条方程在%p下的解. 我看了网上的题解说是高斯消元 + 扩展欧几里德. 然后我自己想了想,就用了高斯消元 + 费马小定理.因为%p是质数,所以很容易就用上了费马小定理,就是在除法的时候用一次就好了.还有就是两个模数相乘还要模一次. #include <cstdio> #include <cstdlib> #include <cstring> #inc

POJ 2947-Widget Factory(高斯消元解同余方程式)

题目地址:id=2947">POJ 2947 题意:N种物品.M条记录,接写来M行,每行有K.Start,End,表述从星期Start到星期End,做了K件物品.接下来的K个数为物品的编号. 此题注意最后结果要调整到3-9之间. 思路: 非常easy想到高斯消元. 可是是带同余方程式的高斯消元,開始建立关系的时候就要MOD 7 解此类方程式时最后求解的过程要用到扩展gcd的思想,举个样例,假设最后得到的矩阵为: 1  1   4 0  6   4 则6 * X2 % 7= 4 % 7  则

UVA 1563 - SETI (高斯消元+逆元)

UVA 1563 - SETI 题目链接 题意:依据题目那个式子.构造一个序列,能生成对应字符串 思路:依据式子能构造出n个方程.一共解n个未知量,利用高斯消元去解,中间过程有取摸过程.所以遇到除法的时候要使用逆元去搞 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 105; int pow_mod(int x, int k,