正三十邊形的對角線可將其為多少部分

來源:互聯網
上載者:User

From http://218.1.231.240/iqbbs/dispbbs.asp?boardid=16&id=152836

最後計算出來是21480個地區。







 

 

首先計算交點數目:計算結果為16801個交點

假設Z=exp(Pi/15*i)=cos(Pi/15)+i*sin(Pi/15)

那麼Z^15=-1, Z^30=1.點1,Z,Z^2,...,Z^29在複平面上構成正30邊形。

而Z的極小多項式是1+Z-Z^3-Z^4-Z^5+Z^7+Z^8。

也就是上面表達是關於Z是0,而任意次數低於8的有理係數多項式,不可能在Z這點取0。(不包括0多項式)

這個多邊形所有頂點都是Q[Z]中的點(也就是所有有理係數多項式將Z代入後可能的取值),所以它們對角線的交點

也會在Q[Z]中。現在我的演算法就是將每個對角線的交點用關於Z的次數低於8的有理多項式表示出來,這種表示方法必然是唯一的。如果兩個交點它們的多項式相同,那麼就是同一個點,不然不同。

第一個程式,計算所有的交點,並輸出,輸出格式是每行都是


a,b,c,d,e,f,g,h[i,j,s,t]


其中前面8個數表示這個交點是
a+bZ+cZ^2+dZ^3+eZ^4+fZ^5+gZ^6+hZ^7


後面四個數表示這個點是直線Z^i Z^j 和 直線Z^s Z^t的交點。


#include <stdio.h>
#include <process.h>
__int64 factor(__int64 a,__int64 b){
if(b==0)return a;
else return factor(b,a%b);
}


class Q{
__int64 _up;
__int64 _down;
void Normalize(){
__int64 fac=factor(_up,_down);
_down/=fac;
_up/=fac;
if(_down<0){
_down=-_down;
_up=-_up;
}
}
public:
Q():_up(0),_down(1){}
Q(__int64 up,__int64 down):_up(up),_down(down){}
Q(__int64 x):_up(x),_down(1){}
Q& operator+=(const Q& x);
Q& operator-=(const Q& x);
Q& operator*=(const Q& x);
Q& operator/=(const Q& x);
Q operator-()const{Q tmp=*this;tmp._up=-_up;return tmp;}
Q operator+(const Q& x)const{Q tmp=*this;tmp+=x;return tmp;}
Q operator-(const Q& x)const{Q tmp=*this;tmp-=x;return tmp;}
Q operator*(const Q& x)const{Q tmp=*this;tmp*=x;return tmp;}
Q operator/(const Q& x)const{Q tmp=*this;tmp/=x;return tmp;}
bool iszero()const{return _up==0;}
bool operator==(const Q& x)const{return _up==x._up&&_down==x._down;}
void output()const{if(_down==1)printf("% 4I64d",_up);else printf("% 2I64d/%I64d",_up,_down);}
};


Q& Q::operator +=(const Q& x){
_up=_up*x._down+_down*x._up;
_down*=x._down;
Normalize();
return *this;
}


Q& Q::operator -=(const Q& x){
_up=_up*x._down-_down*x._up;
_down*=x._down;
Normalize();
return *this;
}


Q& Q::operator *=(const Q& x){
_up*=x._up;
_down*=x._down;
Normalize();
return *this;
}


Q& Q::operator /=(const Q& x){
_up*=x._down;
_down*=x._up;
Normalize();
return *this;
}


Q mod[9]={Q(1),Q(1),Q(0),Q(-1),Q(-1),Q(-1),Q(0),Q(1),Q(1)};


void Mod(Q a[15]){
int i,j;
for(i=14;i>=8;i--){
Q divider=a[ i ];
for(j=0;j<=8;j++){
a[i-j]-=divider*mod[8-j];
}
}
}


void Dump(const Q M[15][15], const Q b[15]){
int i,j;
printf("//n//n");
for(i=0;i<15;i++){
for(j=0;j<14;j++){
M[j][ i ].output();
printf(",");
}
M[j][ i ].output();
printf("=");
b[ i ].output();
printf("//n");
}
}


void SolveEquation(Q M[8][8],Q b[15]){
int i,j,k;
for(i=0;i<8;i++){
// Dump(M,b);
for(j=i;j<8;j++)
if(!M[ i ][j].iszero())break;
if(j!=i){
if(j>=8){
printf("There/'s no inverse for the matrix//n");
exit(-1);
}
for(k=0;k<8;k++){
Q tmp=M[k][ i ];
M[k][ i ]=M[k][j];
M[k][j]=tmp;
}
Q tmp=b[ i ];
b[ i ]=b[j];
b[j]=tmp;
}
Q divider=M[ i ][ i ];
for(j=i;j<8;j++)M[j][ i ]/=divider;
b[ i ]/=divider;
for(j=0;j<8;j++){
if(j==i)continue;
Q mult=M[ i ][j];
for(k=i;k<8;k++)M[k][j]-=mult*M[k][ i ];
b[j]-=mult*b[ i ];
}
}
}

void Inverse(const Q a[15], Q b[15]){
Q M[8][8];
Q tmp[15];
int i,j;
for(i=0;i<8;i++){
for(j=0;j<15;j++)tmp[j]=Q(0);
for(j=0;j<8;j++)tmp[i+j]=a[j];
Mod(tmp);
for(j=0;j<8;j++){
M[ i ][j]=tmp[j];
}
}
b[0]=Q(1);
for(i=1;i<15;i++)b[ i ]=Q(0);
SolveEquation(M,b);
}


void Multiple(const Q a[15], const Q b[15], Q c[15]){
int i,j;
for(i=0;i<15;i++)c=Q(0);
for(i=0;i<15;i++)for(j=0;j<15;j++){
if(i+j<15){
c[i+j]+=a[ i ]*b[ j ];
}else{
c[i+j-15]-=a[ i ]*b[ j ];
}
}
Mod(c);
}


void Output(const Q r[15],int i,int j,int s,int k){
int u;
for(u=0;u<7;u++){
r[u].output();
printf(",");
}
r[u].output();
printf("[%d,%d,%d,%d]//n",i,j,s,k);
}


#define INC(z, x) do{//
int tmp=(x)%30;if(tmp<0)tmp+=30;//
if(tmp<15)(z)[tmp]+=Q(1);//
else (z)[tmp-15]-=Q(1);//
}while(0)


#define DEC(z, x) do{//
int tmp=(x)%30;if(tmp<0)tmp+=30;//
if(tmp<15)(z)[tmp]-=Q(1);//
else (z)[tmp-15]+=Q(1);//
}while(0)


void Find(int i,int j,int s,int t){
int k;
// printf("%d %d %d %d//n",i,j,s,t);
Q delta[15],invdelta[15],r[15];
for(k=0;k<15;k++){
delta[k]=0;
}
INC(delta,j-t);DEC(delta,i-t);DEC(delta,j-s);INC(delta,i-s);
DEC(delta,t-j);INC(delta,t-i);INC(delta,s-j);DEC(delta,s-i);
Mod(delta);
Inverse(delta,invdelta);
for(k=0;k<15;k++)delta[k]=0;
INC(delta,i-j+s);DEC(delta,i-j+t);DEC(delta,-i+j+s);INC(delta,-i+j+t);
INC(delta,j+s-t);DEC(delta,i+s-t);DEC(delta,j-s+t);INC(delta,i-s+t);
Mod(delta);
Multiple(invdelta,delta,r);
Output(r,i,j,s,t);
}


int main(){
int i,j,s,t;
for(i=0;i<30;i++)for(s=i+1;s<30;s++)for(j=s+1;j<30;j++)for(t=j+1;t<30;t++){
Find(i,j,s,t);
}
}

上面的程式可以給出每條對角線上經過那些交點,每個交點有多少對角線經過,有了這個資訊,接下去很簡單。

上面程式還不能直接算出交點數目,需要對輸出結果線排序(用sort命令就可以了),然後通過電腦處理出去冗餘的點,就可以數出結果了。

最後計算出來是21480個地區。
計算公式是Sum{(d(i)-1), d(i)是第i個交點經過的對角線數目}+1+L, L是對角線的數目。
這裡c30.sort.txt是上面的程式的輸出結果排序後的結果。


#include <stdio.h>
#include <string.h>
#define MAXSIZE 100
struct Intersect{
int i,j,s,t;
}Backup[MAXSIZE];
struct Points{
int x,y;
}Tmp[MAXSIZE];
int DumpPoints(FILE *out, char *result,int lcount)
{
int c,i,j;
fprintf(out,"%s[",result);
for(i=0,c=0;i<lcount;i++){
int x,y;
x=Backup[ i ].i;y=Backup[ i].j;
for(j=0;j<c;j++){
if(Tmp[j].x==x&&Tmp[j].y==y)break;
}
if(j==c){
Tmp[j].x=x;Tmp[j].y=y;
c++;
}
x=Backup[ i ].s;y=Backup[ i ].t;
for(j=0;j<c;j++){
if(Tmp[j].x==x&&Tmp[j].y==y)break;
}
if(j==c){
Tmp[j].x=x;Tmp[j].y=y;
c++;
}
}
for(i=0;i<c;i++){
fprintf(out,"(%d,%d)",Tmp[ i ].x,Tmp[ i ].y);
}
fprintf(out,"]//n");
return c;
}


 


int main()
{
char buf[100];
char prev[100]="";
char *p, *q;int lcount=0,scount=0;
int i,j,s,t,sum;
FILE *in=fopen("c30.sort.txt","r");
FILE *out=fopen("c30.dup.txt","w");
q=prev;sum=0;
while(!feof(in)){
fgets(buf,100,in);
p=strchr(buf,/'[/');
if(p==NULL)continue;
*p=/'//0/';p++;
if(strcmp(buf,prev)){//Start new string
int c=DumpPoints(out,prev,lcount);
if(c>0)sum+=c-1;
lcount=0;
strcpy(prev,buf);
q=prev+(p-buf);
strcpy(q,p);
scount=0;
}
sscanf(p,"%d,%d,%d,%d",&i,&j,&s,&t);
if(lcount<MAXSIZE){
Backup[lcount].i=i;Backup[lcount].j=j;Backup[lcount].s=s;Backup[lcount].t=t;
}
if(j-i!=15&&t-s!=15){
scount++;
}
lcount++;
}
sum+=DumpPoints(out,prev,lcount)-1;
fclose(in);
fclose(out);
printf("Total %d//n",sum+15*27+1);
}

 


 下面是一個通過google找到的公式:


--  作者:duz
--  發布時間:2005-3-11 9:37:41
--  
關於本題的一個pdf檔案 :http://math.berkeley.edu/~poonen/papers/ngon.pdf

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.