zoukankan      html  css  js  c++  java
  • Poj 2065 SETI (高斯消元)

    题目连接:

      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
    ", x[var-1]);
    73     }
    74     return 0;
    75 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    LNMP源码编译安装(centos7+nginx1.9+mysql5.6+php7)
    linux 最大文件查找
    Nginx 日志分享
    ZendGuardLoader安装
    移动端播放直播流(video.js 播放 m3u8 流)
    Linux下 PostgrelSQL 基本操作
    CenterOS7 安装Mysql8 及安装会遇到的问题
    Linux下 导出postgrelSql 数据库
    《编译程序设计原理与技术》笔记之自动机与正规表达式
    Linux定时检测内存,若使用率超过指标,重启Tomcat并清空内存
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4628874.html
Copyright © 2011-2022 走看看