1. 程式人生 > >HDU 1427 速算24點【數值型DFS】

HDU 1427 速算24點【數值型DFS】

tar include 任務 div accepted ostream while accep urn

速算24點

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2562 Accepted Submission(s): 606


Problem Description 速算24點相信絕大多數人都玩過。就是隨機給你四張牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用‘+‘,‘-‘,‘*‘,‘/‘運算符以及括號改變運算順序,使得最終運算結果為24(每個數必須且僅能用一次)。遊戲很簡單,但遇到無解的情況往往讓人很郁悶。你的任務就是針對每一組隨機產生的四張牌,判斷是否有解。我們另外規定,整個計算過程中都不能出現小數。 Input 每組輸入數據占一行,給定四張牌。 Output 每一組輸入數據對應一行輸出。如果有解則輸出"Yes",無解則輸出"No"。 Sample Input A 2 3 6 3 3 8 8 Sample Output Yes No 【分析】:

簡單的DFS,dfs(sum,next,p)表示當前已經算出的值是sum,括號中算出的值是next,當前使用的卡片下標為p,實際上是把括號外和括號內的兩部分值分成sum和next來處理了。

直覺告訴我們4個數只需要一層括號參與運算就夠了,不會也不必用多重括號改變運算順序,因此上面的dfs思路是正確的。

那麽對於下一張卡片,有兩種處理方式:

1、把next算入sum中,下一張卡片成了新的括號中的算式的值。

2、把下一張卡片的值算入next中,下一張卡片加入了括號中。

這道題直接暴力有點不和諧,所以可以用next_permutation()來做,總結一下,其實所有運算都可以歸結為兩類,一類是( ( [email protected]) @c) @d 另一類是 ( [email protected] ) @ ([email protected]) 因為只有四個數,所以這麽做沒問題,但當操作數增多的時候就有點麻煩了,這時候可以考慮遞歸來做

對於上述兩種處理方式,每種方式又分成加減乘除四種情況討論,而對於除法這種情況需要特殊處理,除數不能為0,而且題目中要求運算過程中不能出現小數,因此在做除法運算前需要檢查。

【代碼】:

技術分享
#include <iostream>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <string>  
#include <algorithm>  
  
using namespace std;  
  
int cardNum[10]; //cardNum[i]=第i張牌的數字大小 bool flag=false; //flag=true表明能算出24點 int getNum(string s) //撲克牌編號s轉數字 { if(s[0]>=2&&s[0]<=9) return s[0]-0; if(s=="10") return 10; switch(s[0]) { case A: return 1; case J: return 11; case Q: return 12; case K: return 13; } } void dfs(int sum,int next,int p) //表示當前已經算出的值是sum,括號中算出的值是next,當前使用的卡片下標為p { if(p==4) //正在用第4張牌 { if(sum+next==24||sum-next==24||sum*next==24) flag=true; if(next!=0&&sum%next==0&&sum/next==24) flag=true; return; } //1、不加括號 dfs(sum+next,cardNum[p+1],p+1); dfs(sum-next,cardNum[p+1],p+1); dfs(sum*next,cardNum[p+1],p+1); if(next!=0&&sum%next==0) dfs(sum/next,cardNum[p+1],p+1); //2、加括號,則需要改變運算順序 dfs(sum,next+cardNum[p+1],p+1); dfs(sum,next-cardNum[p+1],p+1); dfs(sum,next*cardNum[p+1],p+1); if(cardNum[p+1]!=0&&next%cardNum[p+1]==0) dfs(sum,next/cardNum[p+1],p+1); } int main() { string in; while(cin>>in) { flag=false; cardNum[1]=getNum(in); for(int i=2;i<=4;i++) { cin>>in; cardNum[i]=getNum(in); } sort(cardNum+1,cardNum+5); do { dfs(cardNum[1],cardNum[2],2); }while(!flag&&next_permutation(cardNum+1,cardNum+5)); if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }
數值型DFS

HDU 1427 速算24點【數值型DFS】