思路:簡單的DFS,dfs(sum,next,p)表示當前已經算出的值是sum,括號中算出的值是next,當前使用的卡片下標為p,實際上是把括號外和括號內的兩部分值分成sum和next來處理了。
直覺告訴我們4個數只需要一層括號參與運算就夠了,不會也不必用多重括號改變運算順序,因此上面的dfs思路是正確的。
那麼對於下一張卡片,有兩種處理方式:
1、把next算入sum中,下一張卡片成了新的括號中的算式的值。
2、把下一張卡片的值算入next中,下一張卡片加入了括號中。
對於上述兩種處理方式,每種方式又分成加減乘除四種情況討論,而對於除法這種情況需要特殊處理,除數不能為0,而且題目中要求運算過程中不能出現小數,因此在做除法運算前需要檢查。
#include#include #include #include #include #include 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 ); else printf(No ); } return 0; }