随笔 - 97, 文章 - 22, 评论 - 81, 引用 - 0
数据加载中……

Pku 3361 Gaussian Prime Factors (数论)

问题描述:
求一个整数的高斯素因子。
解题思路:
高斯整数a + bi是素数当且仅当:
1)a、b中有一个是零,另一个数的绝对值是形如4n + 3的素数;
2)a、b均不为零,而a2 + b2为素数;
于是只要将每个分解素因子,对于每个素因子P,如果该素因子形如4n+3,则必定能分解成(a+bj)(a-bj) = a^2 + b^2,枚举解决。

代码如下:
#include <iostream>
#include 
<cmath>
using namespace std;

int f[65537], p[65537], size;
int pri[1000], top;
int n;

struct point
{
    
int a;
    
int b;
    
char oper;
}
s[10000];
int num;

//筛选素数
void init()
{
    f[
1= 1;
    
int i, j;
    
for(i = 2; i <= 65536; i++)
    
{
        
if(!f[i])
        
{
            p[ size
++ ] = i;
            
for(j = i+i; j <= 65536; j += i)
                f[j] 
= 1;
        }

    }

}


//素因子分解
void Flip(int key)
{
    
int i;
    top 
= 0;
    
for(i = 0; i < size; i++)
    
{
        
if(key % p[i] == 0)
        
{
            pri[ top
++ ] = p[i];
            key 
/= p[i];

            
while(key % p[i] == 0){
                pri[ top
++ ] = p[i];
                key 
/= p[i];
            }

        }

    }


    
if(key - 1)
        pri[ top
++ ] = key;
}


//高斯素数分解
void Part(int prime)
{
    
int i;
    
if(prime == 2)
    
{
        s[ num ].a 
= 1; s[ num ].b = 1; s[ num++ ].oper = '+';
        s[ num ].a 
= 1; s[ num ].b = 1; s[ num++ ].oper = '-';
    }
else if( (prime - 1% 4 == 0)
    
{
        
for(i = 1; ;i++)
        
{
            
int u = int(sqrt(prime - i*i*1.0+ 1e-5);
            
if(u*+ i*== prime)
            
{
                s[ num ].a 
= i; s[ num ].b = u; s[ num++ ].oper = '+';
                s[ num ].a 
= i; s[ num ].b = u; s[ num++ ].oper = '-';
                
break;
            }

        }

    }
else
    
{
        s[ num ].a 
= prime; s[ num++ ].b = 0;
    }

}


int cmp(const void *a, const void *b)
{
    point 
*= (point *)a;
    point 
*= (point *)b;
    
if(c->!= d->a)
        
return c->- d->a;
    
if(c->!= d->b)
        
return c->- d->b;
    
return c->oper == '-' ? 1 : -1;
}


void Print(int key)
{
    printf(
"%d", s[key].a );
    
    
if(s[key].b == 0)
        
return;

    
if(s[key].b == 1)
    
{
        printf(
"%cj", s[key].oper);
    }
else
    
{
        printf(
"%c%dj", s[key].oper, s[key].b);
    }


}


int main()
{
    init();
    
int i, cas = 1;

    
while(scanf("%d"&n) != EOF)
    
{
        num 
= 0;
        Flip(n);
        
for(i = 0; i < top; i++)
        
{
            Part(pri[i]);
        }


        qsort(s, num, 
sizeof(point), cmp);
        printf(
"Case #%d: ", cas++);
        Print(
0);
        
for(i = 1; i < num; i++)
        
{
            
if(s[i].a == s[i-1].a
                
&& s[i].b == s[i-1].b
                
&& s[i].oper == s[i-1].oper)
                
continue;
            
if(i)
                printf(
"");
            Print(i);
        }

        puts(
"");
    }

}

posted on 2009-02-10 20:05 英雄哪里出来 阅读(495) 评论(0)  编辑 收藏 引用 所属分类: ACM


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理