24点(伪题解)
?題目傳送門:https://www.luogu.org/problemnew/show/P1236
這個(gè)題dalao都是用后綴表達(dá)式做的,而我這種蒟蒻什么都不會(huì)只能強(qiáng)行爆搜失敗。思路簡(jiǎn)單:假設(shè)輸入的四個(gè)數(shù)為6 6 6 6,那么我們可以看出答案可以為6+6+6+6=24或6*6-6-6=24,那么無(wú)論如何式子都是由三個(gè)運(yùn)算符號(hào)和四個(gè)數(shù)字組成的,那么在dfs(i)中我們根據(jù)i的奇偶來(lái)判斷枚舉的是什么(奇數(shù)位數(shù)字,偶數(shù)位運(yùn)算符最后i==8時(shí)判斷)。注意點(diǎn):題目中要求+或*時(shí)兩數(shù)若有大小先輸大小(頭腦發(fā)昏的我開(kāi)始-和/都交換了位置),不要忘記了1 3 5 7,這種由兩部分分別運(yùn)算最后合起來(lái)的式子(3-1=2,7+5=12,12*2=24)。
那么最后來(lái)解釋一下為什么說(shuō)是偽題解,以下程序它本身非常神奇地?zé)o法處理輸入的四個(gè)數(shù)中有重復(fù)的數(shù)且無(wú)解的情況(貌似是棧溢出了但我弄了兩個(gè)小時(shí)也沒(méi)弄好),直到我火了,我開(kāi)始用一個(gè)sum1判斷這個(gè)輸入有無(wú)重復(fù)的數(shù),再用sum規(guī)定在有重復(fù)的數(shù)(即sum1=1)有一個(gè)搜索底線(不太好用深度或廣度來(lái)形容),簡(jiǎn)單的說(shuō),就是讓它在棧溢出的邊緣瘋狂試探,搜索時(shí)不再死循環(huán)。以下為代碼(這個(gè)300多行的代碼令人神魂顛倒盡管很多是復(fù)制的):
#include<stdio.h> #include<stdlib.h> int a[100]={0},step1[100]={0},step2[100]={0},vis[1000]={0}; int flag=0,sum=0,sum1=0; int judge1() {int i,ans;ans=0;for(i=1;i<=3;i++)if(step2[i]==1){if(i==1)ans=step1[i]+step1[i+1];else ans+=step1[i+1];}else if(step2[i]==2){if(i==1)ans=step1[i]-step1[i+1];else ans-=step1[i+1];}else if(step2[i]==3){if(i==1)ans=step1[i]*step1[i+1];else ans*=step1[i+1];}else if(step2[i]==4){if(step1[i]%step1[i+1]!=0) return 0;if(i==1)ans=step1[i]/step1[i+1];else ans/=step1[i+1];}if(ans==24)return 1;return 0; } int judge2() {int i,j,ans1=0,ans2=0;if(step2[1]==1){ans1=step1[1]+step1[2];}else if(step2[1]==2){ans1=step1[1]-step1[2];}else if(step2[1]==3){ans1=step1[1]*step1[2];}else if(step2[1]==4){if(step1[1]%step1[2]!=0) return 0;ans1=step1[1]/step1[2];}if(step2[3]==1){ans2=step1[3]+step1[4];}else if(step2[3]==2){ans2=step1[3]-step1[4];}else if(step2[3]==3){ans2=step1[3]*step1[4];}else if(step2[3]==4){if(step1[3]%step1[4]!=0) return 0;ans2=step1[3]/step1[4];}if(step2[2]==1)ans1=ans1+ans2;else if(step2[2]==2)ans1=ans1-ans2;else if(step2[2]==3)ans1=ans1*ans2;else if(step2[2]==4){if(ans1%ans2!=0)return 0;ans1=ans1/ans2;}if(ans1==24) return 1;return 0; } int write1() {int i,j,ans=0,tmp;if(step2[1]==1){ans=step1[1]+step1[2];if(step1[1]>step1[2])printf("%d+%d=%d\n",step1[1],step1[2],ans);else printf("%d+%d=%d\n",step1[2],step1[1],ans);}else if(step2[1]==2){ans=step1[1]-step1[2];if(step1[1]>step1[2])printf("%d-%d=%d\n",step1[1],step1[2],ans);else printf("%d-%d=%d\n",step1[2],step1[1],ans);}else if(step2[1]==3){ans=step1[1]*step1[2];if(step1[1]>step1[2])printf("%d*%d=%d\n",step1[1],step1[2],ans);else printf("%d*%d=%d\n",step1[2],step1[1],ans);}else if(step2[1]==4){ans=step1[1]/step1[2];if(step1[1]>step1[2])printf("%d/%d=%d\n",step1[1],step1[2],ans);else printf("%d/%d=%d\n",step1[2],step1[1],ans);}for(i=2;i<=3;i++)if(step2[i]==1){tmp=ans;ans+=step1[i+1];if(tmp>step1[i+1])printf("%d+%d=%d\n",tmp,step1[i+1],ans);else printf("%d+%d=%d\n",step1[i+1],tmp,ans);}else if(step2[i]==2){tmp=ans;ans-=step1[i+1];printf("%d-%d=%d\n",tmp,step1[i+1],ans);}else if(step2[i]==3){tmp=ans;ans*=step1[i+1];if(tmp>step1[i+1])printf("%d*%d=%d\n",tmp,step1[i+1],ans);else printf("%d*%d=%d\n",step1[i+1],tmp,ans);}else if(step2[i]==4){tmp=ans;ans/=step1[i+1];printf("%d/%d=%d\n",tmp,step1[i+1],ans);}return 0; } int write2() {int i,ans1=0,ans2=0;if(step2[1]==1){ans1=step1[1]+step1[2];if(step1[1]>step1[2])printf("%d+%d=%d\n",step1[1],step1[2],ans1);else printf("%d+%d=%d\n",step1[2],step1[1],ans1);}else if(step2[1]==2){ans1=step1[1]-step1[2];if(step1[1]>step1[2])printf("%d-%d=%d\n",step1[1],step1[2],ans1);else printf("%d-%d=%d\n",step1[2],step1[1],ans1);}else if(step2[1]==3){ans1=step1[1]*step1[2];if(step1[1]>step1[2])printf("%d*%d=%d\n",step1[1],step1[2],ans1);else printf("%d*%d=%d\n",step1[2],step1[1],ans1);}else if(step2[1]==4){ans1=step1[1]/step1[2];printf("%d/%d=%d\n",step1[1],step1[2],ans1);}if(step2[3]==1){ans2=step1[3]+step1[4];if(step1[3]>step1[4])printf("%d+%d=%d\n",step1[3],step1[4],ans2);else printf("%d+%d=%d\n",step1[4],step1[3],ans2);}else if(step2[3]==2){ans2=step1[3]-step1[4];printf("%d-%d=%d\n",step1[3],step1[4],ans2);}else if(step2[3]==3){ans2=step1[3]*step1[4];if(step1[3]>step1[4])printf("%d*%d=%d\n",step1[3],step1[4],ans2);else printf("%d*%d=%d\n",step1[4],step1[3],ans2);}else if(step2[3]==4){ans2=step1[3]/step1[4];printf("%d/%d=%d\n",step1[3],step1[4],ans2);}if(step2[2]==1){if(ans1>ans2)printf("%d+%d=24\n",ans1,ans2);else printf("%d+%d=24\n",ans2,ans1);}else if(step2[2]==2){if(ans1>ans2)printf("%d-%d=24\n",ans1,ans2);else printf("%d-%d=24\n",ans2,ans1);}else if(step2[2]==3){if(ans1>ans2)printf("%d*%d=24\n",ans1,ans2);else printf("%d*%d=24\n",ans2,ans1);}else if(step2[2]==4){if(ans1>ans2)printf("%d/%d=24\n",ans1,ans2);else printf("%d/%d=24\n",ans2,ans1);}return 0; } int dfs(int i) {int j;sum++;if(i==8){if(judge1()==1){flag=1;write1();}return 0;}if(flag==1)return 0;if(sum>3700&&sum1==1) return 0;if(sum>5000) return 0;if(i%2==1){for(j=1;j<=4;j++)if(vis[j]==0){step1[i/2+1]=a[j];vis[j]=1;dfs(i+1);if(sum>3700&&sum1==1) return 0;if(sum>5000) return 0;step1[i/2+1]=0;vis[j]=0;}}else{for(j=1;j<=4;j++){step2[i/2]=j;dfs(i+1);if(sum>3700&&sum1==1) return 0;if(sum>5000) return 0;step2[i/2]=0;}}return 0; } int dfs2(int i) {int j;sum++;if(i==8){if(judge2()==1){flag=1;write2();}return 0;}if(flag==1)return 0;if(sum>3700&&sum1==1) return 0;if(sum>5000) return 0;if(i%2==1){for(j=1;j<=4;j++)if(vis[j]==0){step1[i/2+1]=a[j];vis[j]=1;dfs2(i+1);if(sum>3700&&sum1==1) return 0;if(sum>5000) return 0;step1[i/2+1]=0;vis[j]=0;}}else{for(j=1;j<=4;j++){step2[i/2]=j;dfs2(i+1);if(sum>3700&&sum1==1) return 0;if(sum>5000) return 0;step2[i/2]=0;}}return 0; } int main() {int n,i;for(i=1;i<=4;i++){scanf("%d",&a[i]);if(vis[a[i]]==0)vis[a[i]]=1;else sum1=1;}memset(vis,0,sizeof(vis));dfs(1);if(flag==0){sum=0;dfs2(1);if(flag==0)printf("No answer!");}return 0; }?
總結(jié)
- 上一篇: Java中的专业术语
- 下一篇: 电脑小白必备的52个专业术语,有必要了解