C_and_CPP 板


LINE

題目網址: http://www.tcgs.tc.edu.tw/~sagit/luckycat/q167.htm 小弟後來找到是自己DFS的方式不對 所以我換了個做法 直接從座標(0,0)開始跑 跑到有8個皇后在stack陣列裡 就累加出答案 之後跟sum比較大小 大就取代sum反之不動 不過方法有點暴力 第一個解我就搜了快4000次... 我搜到第27組解的時候就程式就停住了 希望高手能幫我看看 感謝高手幫忙XD ===========以下為程式碼============= /*8 queens*/ #include<stdio.h> #include<string.h> #include<stdlib.h> int use[8][8]={},value[8][8]={},queens[8][8]={},sum=0 ,solution=0,times=0,stack[8]={},top=-1; int get_can_use(int (*map)[8],int x,int y); void action(int (*map)[8],int coordinate,int do_now); void DFS(int x,int y); int pop(int *stack,int top); int push(int *stack,int value,int top); int get_value(int (*value_adress)[8],int total); void put_stack(); void output(int (*map)[8],int number){ /*測試用*/ int x,y,i,k; memset(queens,0,sizeof(queens)); printf("queens=%d\n",number); /*queens代表目前有幾個queen再stack裡*/ for(k=0;k<=top;k++){ queens[stack[k]/10][stack[k]%10]=1; printf("%d ",stack[k]); } printf("\n"); /*印出皇后圖 1為皇后位置 0等於未放置*/ for(y=0;y<8;y++){ for(x=0;x<8;x++){ printf("%d ",queens[x][y]); } printf("\n"); } printf("\n"); for(y=0;y<8;y++){ for(x=0;x<8;x++){ printf("%d ",map[x][y]); } printf("\n"); } /*印出實際DFS的地圖*/ printf("\n"); put_stack(); } int main(){ int k,d; while ( ~scanf("%d",&k)){ memset(use,0,sizeof(use)); memset(value,0,sizeof(value)); int i,j,target,u,l,replace; for(;k>0;k--){ int total_replace=0; /*儲存資料*/ for(i=0;i<8;i++){ for(j=0;j<8;j++){ scanf("%d",&value[j][i]); } } DFS(0,0); printf("sum=%d\n",sum); } } return 0; } int get_can_use(int (*map)[8],int x,int y){/*抓出可放皇后的點*/ int target_x,target_y,find=0; target_y=y;target_x=x;/*從傳入的XY座標開始找*/ for(;target_y<8&&find==0;target_y++){ for(;target_x<8;target_x++){ if(map[target_x][target_y]==0){ find=1; /*找到即跳出*/ break; } } (find==1)?:target_x=0;/*一橫行已結束 X值歸0繼續找*/ if(find==1){ break; /*找到立即跳出 這樣才不影響Y值*/ } } if(find==1){ x=target_x*10+target_y; /*target_x target_y皆為函式內宣告 傳出會有問題*/ return x; /*target=x*10+y*/ } else{ /*找不到點*/ return 100; } } void action(int (*map)[8],int coordinate,int do_now){ /*皇后點=x*10+y 動作(do_now)=1=>放 動作(do_now)=-1=>移除*/ int start_x,start_y,method,x,y,add_number,left_up=100,left_down=100 ,change,down=0,up=0; start_x=coordinate/10; start_y=coordinate%10; for(x=0;x<8;x++){/*直線走法*/ map[x][start_y]+=do_now; } for(y=0;y<8;y++){/*橫線走法*/ map[start_x][y]+=do_now; } /*找斜左上跟左下的點 之後用迴圈一路跑*/ for(change=1;(down==0)||(up==0);change++){ if((((start_x-change)<0)||((start_y-change)<0))&&(up==0)){ left_up=(start_x-change+1)*10+(start_y-change+1); up=1; } if(((start_x-change<0)||(start_y+change>7))&&(down==0)){ left_down=(start_x-change+1)*10+(start_y+change-1); down=1; } } /*將迴圈跳出條件歸0 重複使用*/ up=0;down=0; for(add_number=0;(down==0)||(up==0);add_number++){/*對角線走法*/ if(((left_up/10)+add_number>7)||((left_up%10)+add_number>7)){ up=1; } else if(up==0){ map[(left_up/10)+add_number][(left_up%10)+add_number]+=do_now; } if(((left_down/10)+add_number>7)||((left_down%10)-add_number<0)){ down=1; } else if(down==0){ map[(left_down/10)+add_number][(left_down%10)-add_number]+=do_now; } } map[start_x][start_y]+=(-1)*(do_now*3);/*皇后點重複做了了4次 把他扣回去*/ } /*replace等於從x y開始搜尋後第一個找出可以放皇后的點 找到之後放入stack(一樣是x座標*10+y座標) solution是計算第幾個解 times是計算DFS跑了幾次 如果找不到點 又第一個皇后位置不再第一橫行 DFS跳出(因為每一橫行皆要有皇后) */ void DFS(int x,int y){ int replace,replace_sum,replace_stack; if(top==7){/*有7個皇后就累加答案*/ replace_sum=get_value(value,replace_sum); sum=(replace_sum>sum)?replace_sum:sum; //printf("scuess replace_sum=%d\n",replace_sum); /*測試用*/ put_stack(); solution++; printf("solution=%d times=%d TOP=%d\n",solution,times,top); } replace=get_can_use(use,x,y); //printf("target=%d\n",replace); if(replace==100){ times++; if(stack[0]%10>0){ //printf("break\n"); //output(use,top); return ; } replace_stack=stack[top]; action(use,stack[top],-1); top=pop(stack,top); replace_stack=(replace_stack/10+1)>7?replace_stack%10+1:replace_stack+10; /*這行是要把新的DFS遞迴搜尋開始點設成後面一個點 為防止X軸加1超過8所設計*/ DFS(replace_stack/10,replace_stack%10); } else{ times++; action(use,replace,1); top=push(stack,replace,top); DFS(replace/10,replace%10); } } int get_value(int (*value_adress)[8],int total){/*get sum from stack*/ /*get value from stack*/ int number,i,j; total=0;/*這裡不歸0會怪怪的*/ for(number=0;number<8;number++){ total+=value_adress[stack[number]/10][stack[number]%10]; queens[stack[number]/10][stack[number]%10]=1; }/*不一邊存資料一邊將stack移出是因為還要繼續使用*/ return total; } int pop(int *stack,int top){ if(top==-1){ return -1; } else{ stack[top]=0; top--; return top; } } int push(int *stack,int value,int top){ if(top==7){ return 8; } else{ top++; stack[top]=value; return top; } } void put_stack(){/*印出stack目前有的資料*/ int i; printf("#"); for(i=0;i<=top;i++){ printf("%d ",stack[i]/10); } printf("\n\n"); } --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 210.60.161.254 ※ 編輯: seedpk5079 來自: 210.60.161.254 (06/22 14:49) ※ 編輯: seedpk5079 來自: 210.60.161.254 (06/22 14:51)







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP