Fancy Mouse
- -|||

DFS(深搜),注意优化一下剪枝和求最小未使用数这两部分的代码就行了。 

#include<iostream>
using namespace std;

int PrimeList[50];
int board[100];
int NumUsed[101],MinNum;
int size;
void Solve();
int Acceptable(int k,int cur);
int IsPrime(int k);
int main()
{
    
int data,i,j,k,flag;
    cin
>>data;
    PrimeList[
0= 2;
    PrimeList[
1= k = 3;
    
for(i=2;i<50;i++)
    
{
        flag 
= 0;
        
while(!flag)
        
{
            k 
+= 2;
            flag 
= 1;
            
for(j=1;j<i;j++)
            
{
                
if(k % PrimeList[j] == 0)
                
{
                    flag 
= 0;
                    
break;
                }

            }

        }

        PrimeList[i] 
= k;
    }
//Generate a prime list    
    while(data-- > 0)
    
{
        cin
>>size;
        Solve();
    }

    
return 0;
}

void Solve()
{
    
int i,j,k,flag,cur = 0;

    
for(i=0;i<100;i++) board[i] = NumUsed[i] = 0;
    MinNum 
= flag = 1;
    
while(cur < size*size)
    
{
        
if(board[0>= size*size)
        
{
            flag 
= 0;
            
break;
        }

        
if(0 == board[cur])
        
{
            k 
= MinNum;
            
if(((cur/size + cur%size) % 2^ (k%2 == 0)) k++;
        }

        
else
            k 
= board[cur] + 2;
        
while(k <= size*size && !Acceptable(k,cur)) k += 2;
        
if(k <= size*size)
        
{
            board[cur
++= k;
            NumUsed[k] 
= 1;
            
if(MinNum == k)
                
while(NumUsed[++MinNum]);
        }

        
else
        
{
            board[cur] 
= 0;
            k 
= board[--cur];
            NumUsed[k] 
= 0;
            
if(MinNum > k) MinNum = k;
        }

    }


    
if(flag)
    
{
        
for(i=0;i<size;i++)
        
{
            cout
<<board[i*size];
            
for(j=1;j<size;j++)
                cout
<<' '<<board[i*size+j];
            cout
<<endl;
        }

    }

    
else
        cout
<<"NO\n";//Print results
}

int Acceptable(int k,int cur)
{
    
if(NumUsed[k]) return 0;
    
int a = cur%size,b = cur/size,flag = 1;
    
if(a > 0) flag = (flag && IsPrime(k + board[cur-1]));
    
if(b > 0) flag = (flag && IsPrime(k + board[cur-size]));
    
return flag;
}

int IsPrime(int k)
{
    
int Min = 0,Max = 49,Mid;
    
while(Min < Max)
    
{
        Mid 
= (Min + Max) / 2;
        
if(PrimeList[Mid] > k) Max = Mid - 1;
        
else if(PrimeList[Mid] < k) Min = Mid + 1;
        
else return 1;
    }

    
return PrimeList[Min] == k;
}
posted on 2005-10-21 22:46  Fancy Mouse  阅读(405)  评论(1编辑  收藏  举报