码迷,mamicode.com
首页 > 其他好文 > 详细

Poj 2065 SETI (高斯消元)

时间:2015-07-08 00:25:38      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

题目连接:

  http://poj.org/problem?id=2065

题目描述:

  给出和明码长度相同的暗码,暗码的每一个字母f(k)都是由明码ai按照 f (k) = ∑0<=i<=n-1i *ki(mod p) 转化而来 ,已知暗码,求出明码?

解题思路:

  使用高斯消元,重要的就是模型转化,列出来增广矩阵题目就距离AC不远了。这个题目的增广矩阵为:

  a0*1^0 + a1*1^1 + a2*1^2 + ........ + an*1^n = f(1)(mod p);

  a0*2^0 + a1*2^1 + a2*2^2 + ........ + an*2^n = f(2)(mod p);

  a0*3^0 + a1*3^1 + a2*3^2 + ........ + an*3^n = f(3)(mod p);

           ...

           ...

           ...

  a0*(n-2)^0 + a1*(n-2)^1 + a2*(n-2)^2 + ........ + an*(n-2)^n = f(n-2)(mod p);

  a0*(n-1)^0 + a1*(n-1)^1 + a2*(n-2)^2 + ........ + an*(n-1)^n = f(n-1)(mod p);

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 75;
 7 typedef __int64 LL;
 8 LL det[maxn][maxn], x[maxn];
 9 int  var, equ, p;
10 void gauss ()
11 {
12     int k, col;
13     for (k=col=0; k<equ&&col<var; k++,col++)
14     {
15         int min_i = k;
16         for (int i=k+1; i<equ; i++)//减小误差的出现
17             if (det[min_i][col] < det[i][col])
18                 min_i = i;
19         if (min_i != k)
20             for (int i=col; i<=var; i++)
21                 swap (det[k][i], det[min_i][i]);
22         if (det[k][col] == 0)
23         {
24             k --;
25             continue;
26         }
27         for (int i=k+1; i<equ; i++)
28             if (det[i][col])
29             {
30                 int x, y;//防止精度出现误差
31                 x = det[k][col];
32                 y = det[i][col];
33                 for (int j=col; j<=var; j++)
34                     det[i][j] = (((det[i][j]*x - det[k][j]*y) % p) + p) % p;
35             }
36     }
37     for (int i=k-1; i>=0; i--)
38     {
39         LL temp = det[i][var];
40         for (int j=i+1; j<var; j++)
41             temp = ((temp - det[i][j]*x[j]) % p + p) % p;
42         while (temp%det[i][i])
43             temp += p;//保证结果的精度
44         x[i] = ((temp / det[i][i])%p + p) % p;
45     }
46 }
47 int main ()
48 {
49     int t;
50     scanf ("%d", &t);
51     while (t --)
52     {
53         char str[maxn];
54         scanf ("%d %s", &p, str);
55         var = equ = strlen(str);
56         for (int i=0; i<equ; i++)
57         {
58             LL num = 1;
59             for (int j=0; j<equ; j++)
60             {
61                 det[i][j] = num;
62                 num = (num * (i + 1)) % p;
63             }
64             if (str[i] == *)
65                 det[i][var] = 0;
66             else
67                 det[i][var] = str[i] - a + 1;
68         }
69         gauss ();
70         for (int i=0; i<var-1; i++)
71             printf ("%I64d ", x[i]);
72         printf ("%I64d\n", x[var-1]);
73     }
74     return 0;
75 }

 

Poj 2065 SETI (高斯消元)

标签:

原文地址:http://www.cnblogs.com/alihenaixiao/p/4628874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!