1. 程式人生 > >洛谷 八皇后

洛谷 八皇后

題目傳送門

 好的滿分方法:傳送門

它講的非常詳細,仔細一看方法和我的差不多,不同點在於斜的兩個標記和豎的標記它分別為這個開了三個陣列,然後用來存這裡是否已經被佔領,然後遞迴完下一個再恢復,我本來也想這樣的,但我只想到用一個二維陣列的方法,這樣是不可能回溯的,所以導致我最後一個數據超時而他沒超時

通過這題的收穫是,大的解決不了的時候化成小的,比如說我就應該再多建幾個陣列完成回溯的,可是我沒有想到,很遺憾

 

 

自己的不ok87分方法:

ps.把沒滿分的方法放這是給自己以後看的,程式碼存部落格園比存電腦硬碟好管理多了

思路:

第一次,可以選1,2,3,4,5,6

接下來,每一次選都不能處於前面子的攻擊範圍內,這個用sign標記,然後一直遞迴就好了

評析:

這個做法6~12都可以,但是當n=13時會超時,因為沒有優化過,而且我沒有想到怎麼優化

然後中間除了個錯誤,以後都不寫std::ios::sync_with_stdio(false)了,因為我根本只是照貓畫虎,不懂這東西,很容易出錯

#include<bits/stdc++.h>
using namespace std;
int ans=0,n;
int a[100],sign[100],t=0;

int f(int new_i)
{
    if(new_i==n+1
) { if(t<3){ for(int i=1;i<=n;i++) { printf("%d ",a[i]); } printf("\n"); } ans++; t++; return 0; } for(int i=1;i<=n;i++) { for(int
j=1;j<=new_i-1&&new_i!=1;j++) { sign[a[j]]=1; int left=a[j]-(new_i-j); int right=a[j]+(new_i-j); if(left>=1) sign[left]=1; if(right<=n) sign[right]=1; } if(sign[i]!=1||new_i==1) { a[new_i]=i; memset(sign,0,sizeof(sign)); f(new_i+1); } memset(sign,0,sizeof(sign)); } return 0; } int main() { scanf("%d",&n); f(1); printf("%d",ans); }
給自己看的低分程式碼