给定多项式f(x)=anxn+an-1xn-1+…+a0x0,如果an<>0,我们称f(x)是一个n次多项式。
类似自然数里的“质数”的概念,也可以给出“质多项式”的概念。给定多项式f(x),如果找不到次数至少为1的多项式g(x)和h(x)满足f(x)=g(x)+h(x),我们称f(x)是质多项式。
为了简化起见,我们规定多项式各项的系数只能取两个数:0或1。并且重新定义在{0,1}上的加法和乘法:
0+0=0,0+1=1,1+0=1,1+1=0
0×0=0,0×1=0,1×0=0,0×0=0
下面给出多项式相乘的例子:
(x2+x1)×(x1+1)=x3+x2+x2+x1=x3+x1
.
在这个问题里,你需要写一个程序,对给定的正整数k,求出次数为k的质多项式的。
Simple input |
Output for the input |
1 2 5 13 0
|
X X^2+X+1 X^5+X^2+1 X^13+X^4+X^3+X^1+1 |
解:
观察题目可知这里的的加法运算XOR,其逆运算减法运算也是异或运算XOR。
乘法运算是与运算AND。
于是解题时可以按照穷举法逐个遍历,直到找到解为止。
还有一点需要注意的是K次质多项式必含有X^K和1项。
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int bin[31];
inline void
init(){
int i;
bin[0]=1;
for(i=1;i<=30;i++)
bin[i]=bin[i-1]*2; //bin[i]=2^i
}
inline int
weight(int data){ //返回data中第一个非零位的位置
int i=30;
for(;i>=0;i--)
if(bin[i]<=data) return i;
}
inline void
output(int data){
int i;
for(i=30;i>0;i--){
if(data&bin[i]) printf("x^%d+",i);
}
printf("1 ");
}
inline bool
divide(int a,int b){ //判断b能否整除a
int wa,wb;
wa=weight(a);
wb=weight(b);
b=b<<(wa-wb);
while(a!=b && wa>=wb){
a=a^b; //a=a xor b
while(bin[wa]>a){
--wa;
b=b>>1;
}
}
return wa>=wb? true:false;
}
void
main(){
init();
int k,flag,i,now;
while(1){
scanf("%d",&k);
if(k==0) return;
now=bin[k]-1;
do{
if(now>bin[k+1]) {puts("error");break;}
flag=false;
now+=2;
for(i=2;i<bin[(k+1)/2+1]-1;i++){
if(divide(now,i)==true) {
flag=true;
break;
}
}
}while(flag);
output(now);
}
}
#include<string.h>
#include<stdlib.h>
int bin[31];
inline void
init(){
int i;
bin[0]=1;
for(i=1;i<=30;i++)
bin[i]=bin[i-1]*2; //bin[i]=2^i
}
inline int
weight(int data){ //返回data中第一个非零位的位置
int i=30;
for(;i>=0;i--)
if(bin[i]<=data) return i;
}
inline void
output(int data){
int i;
for(i=30;i>0;i--){
if(data&bin[i]) printf("x^%d+",i);
}
printf("1 ");
}
inline bool
divide(int a,int b){ //判断b能否整除a
int wa,wb;
wa=weight(a);
wb=weight(b);
b=b<<(wa-wb);
while(a!=b && wa>=wb){
a=a^b; //a=a xor b
while(bin[wa]>a){
--wa;
b=b>>1;
}
}
return wa>=wb? true:false;
}
void
main(){
init();
int k,flag,i,now;
while(1){
scanf("%d",&k);
if(k==0) return;
now=bin[k]-1;
do{
if(now>bin[k+1]) {puts("error");break;}
flag=false;
now+=2;
for(i=2;i<bin[(k+1)/2+1]-1;i++){
if(divide(now,i)==true) {
flag=true;
break;
}
}
}while(flag);
output(now);
}
}