【题意】
有n组信息,每组信息代表一个方程组,有几个字母代表有几个未知数,
*代表0,a-z代表1-26,用c[i]表示第i位代表的数
方程组第一个方程为(a1*1^0+a2*1^1+...+an*1^(n-1)) mod p=c[1] mod p
第i个为(a1*i^0+a2*i^1+...+an*i^(n-1)) mod p=c[i] mod p
对于任意ai都大于等于0小于p
输出每组方程组的解
【输入】
第一行n,代表n组信息
接下来n行,第一个数为p,即模的数,接下来是一个不超过70位的字符串
【输出】
每组按a1..an的顺序输出解,两数之间用空格分隔
数据保证每组数据只有一解
类似poj2947
唯一不同的就是模的数会变化,但是值得庆幸的是不用判无解还是多解还是一解了……
老样子从上到下消元,消完元枚举一下值就行了……
program poj2065; type equation=array [0..71] of longint; var i,j,k,n,t,p,q,x,y,z:longint; temp:string; line:array [0..71] of equation; con,point:array [0..71] of longint; space:char; procedure swap_equation (var a,b:equation); var i:equation; begin i:=a; a:=b; b:=i; end; procedure swap_int (var a,b:longint); var i:longint; begin i:=a; a:=b; b:=i; end; procedure swap (a,b:longint); begin swap_equation(line[a],line[b]); swap_int(con[i],con[j]); end; function gcd (a,b:longint):longint; begin if a mod b = 0 then exit(b) else exit(gcd(b,a mod b)); end; procedure gauss; begin for i:=1 to n-1 do begin if line[i][i]=0 then for j:=i+1 to n do if line[j][i]<>0 then begin swap(i,j); break; end; for j:=i+1 to n do if line[j][i]<>0 then begin z:=line[i][i] * line[j][i] div gcd(line[i][i],line[j][i]); x:=z div line[i][i]; y:=z div line[j][i]; con[j]:=((con[j] * y - con[i] * x) mod p + p) mod p; for k:=i to n do line[j][k]:=((line[j][k] * y - line[i][k] * x) mod p + p) mod p; end; end; for i:=n downto 1 do begin k:=con[i]; for j:=i+1 to n do k:=((k-line[i][j]*point[j]) mod p + p) mod p; for j:=0 to p-1 do if j*line[i][i] mod p = k then break; point[i]:=j; end; for i:=1 to n do write(point[i],' '); writeln; end; begin readln(t); while t<>0 do begin read(p); read(space); readln(temp); n:=length(temp); for i:=1 to n do if temp[i]='*' then con[i]:=0 else con[i]:=(ord(temp[i])-96) mod p; for k:=1 to n do begin q:=1; for i:=1 to n do begin line[k,i]:=q; q:=q*k mod p; end; end; gauss; dec(t); end; end.