zoukankan      html  css  js  c++  java
  • poj 2065 SETI

    SETI

    题意:a0, a1, ...an-1 the function f (k) = ∑0<=i<=n-1aiki (mod p) always evaluates to values 0 <= f (k) <= 26 for 1 <= k <= n.

    要求解的是a0, a1, ...an-1;其中 0 <= a0, a1, ...an-1 ,< P。

    a0*10 + a1*11+a2*12+........+an-1*1(n-1)= f(1)

    a0*20 + a1*21+a2*22+........+an-1*2(n-1) = f(2)

    ......

    a0*n0 + a1*n1+a2*n2+........+an-1*n(n-1) = f(n)

    PS:要是看我前面Widget Factory 会发现里面exgcd(a,b,...)在这道题中是个坑。。因为a,b不一定全是正数,并且只要有一个是负数,值正好就是负数(原理同gcd());所以在exgcd()之前把a[i][i]化为正数。还有前面化为上三角阵LCM处求解系数时分母没有加上abs()也是个坑。现已修改~~(no zuo no die!!)

    思路:和Widget Factory 一样,题目没讲清楚是否一定有解,但是输入的数据确实是有唯一解的;(我试了不测试Gauss()的返回值也A了);PS:29983是测试过的素数,可以自己生成字符串来对拍一下(其实我只是从文件输入就发现用大素数测试对WA很有效)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    template <typename T>
    T abs(T a){return a < 0 ? -a:a;}
    template <typename T>
    T min(T a,T b){return a < b?a:b;}
    template <typename T>
    T max(T a,T b){return a < b?b:a;}
    typedef __int64 ll;
    ll a[72][72],x[80];
    int equ,var,MOD;
    void debug()
    {
        puts("********");
        int i,j;
        rep0(i,0,equ){
            rep1(j,0,var)
                cout<<a[i][j]<<" ";
            cout<<endl;
        }puts("********");
    }
    int __gcd(int a,int b)
    {
        return b?__gcd(b,a%b):a;
    }
    int LCM(int a,int b)
    {
        return a/__gcd(a,b)*b;
    }
    void exgcd(int a,int b,int& d,int& x,int& y)
    {
        if(!b){d = a;x = 1;y = 0;}
        else{
            exgcd(b,a%b,d,y,x);
            y -= x*(a/b);
        }
    }
    int Gauss()
    {
        int i,j,k,free_var = 0,row,col;
        for(row = 0,col = 0;row < equ && col < var;row++,col++){
            int mx = row;
            rep0(j,row+1,equ)
                if(abs(a[j][col]) > abs(a[mx][col]))  mx = j;
            if(a[mx][col] == 0){
                row--;  // 行不变;不能通过这里记录自由变元的个数,只能记录没用的col
                continue;
            }
            if(mx != row)
                rep1(k,col,var)
                    swap(a[row][k],a[mx][k]);
            rep0(j,row+1,equ){
                if(a[j][col] != 0){
                    ll lcm = LCM(abs(a[row][col]),abs(a[j][col]));
                    ll ration_row = lcm/abs(a[row][col]),ration_j = lcm/abs(a[j][col]);
                    if(a[row][col]*a[j][col] < 0) ration_row = -ration_row; //符号相反变加法;
                    rep1(k,col,var)
                        a[j][k] = (a[j][k]*ration_j - a[row][k]*ration_row)%MOD;
                }
            }
        }
        //debug();
        rep0(i,row,equ)
            if(a[i][var] != 0) return -1;    //无解
        if(row < var) return var - row;//row表示有用的方程数方程,但是要在判断出有解的前提下才能说有多组解;
        rep_1(i,var - 1,0){  // ***若为唯一解,其实就是var维方阵
            ll ret = a[i][var];
            for(j = i+1;j < var;j++) //利用已求得的变元消去第row行col后面的元素,得到一元方程;
                ret -= x[j]*a[i][j];
            ret = ((ret%MOD)+MOD)%MOD;
            int d,x1,y;
            //构造出 a[i][i]*x[i] + MOD*y = ret(mod MOD);且gcd(a[row][col],7) = 1)因为a[row][col] != 0
            if(a[i][i] < 0) a[i][i] = -a[i][i],ret = -ret;
            exgcd(a[i][i],MOD,d,x1,y); //之后乘上ret弄到3~9范围即可;
            x[i] = ((ret*(x1%MOD))%MOD+MOD)%MOD;
        }
        return 0;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("data2.txt","w",stdout);
        int i,j,T,kase = 1;
        cin>>T;
        while(T--){
            MS0(x);MS0(a);
            char s[80];
            scanf("%d%s",&MOD,s);
            var = equ = strlen(s);
            rep0(i,0,var){
                if(s[i] == '*') a[i][var] = 0;
                else a[i][var] = s[i] - 'a' + 1;
            }
            rep0(i,0,var){
                a[i][0] = 1;
                rep0(j,1,var)
                    a[i][j] = a[i][j-1]*(i+1)%MOD;
            }
            //debug();
            Gauss();
            rep0(i,0,var)
                printf("%I64d%c",x[i],i == var - 1?'
    ':' ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ABP Xunit单元测试 第五篇
    ABP 异常处理 第四篇
    ABP Quartz 作业调度第三篇
    ABP 权限拦截 第二篇
    ABP .NET corej 版本 第一篇
    Vue生命周期
    vue中的import、export、requre的区别
    ES6最新语法
    Vux项目搭建
    对象克隆
  • 原文地址:https://www.cnblogs.com/hxer/p/5182385.html
Copyright © 2011-2022 走看看