xdoj五星題172 構造表達式
標題
構造表達式
類別
綜合
時間限制
1S
內存限制
100Kb
問題描述
給定一個表示序列長度的整數n(3<=n<=9)。在序列1 2 3…n中插入‘+’,‘-’,‘ ’構造表達式,插入‘ ’表示前後兩個數字構成一個整數,例如1 2 -3 -4 -5=0。
輸出構造的所有表達式中,結果爲0的表達式的數量,例如n=3時,只有表達式1+2-3=0,輸出結果爲1。
輸入說明
輸入數據爲一個整數n(n<10),表示序列長度,同時表示輸入序列爲“1 2 3…n”。
輸出說明
對於每一組數據,輸出一個整數,表示構造的表達式中結果爲0的表達式數量。
輸入樣例
3
輸出樣例
1
題目思路:
想用遞歸的方法來整這個題。
快捷的數學方法我是想不到了(QAQ)
目前只想出兩種方法:
**1.**將n個數之間的n-1個空格轉換成三進制,用0代表+,用1代表-,用2代表“ ”,這樣相當於是給了輸入然後用函數去算這個表達式,省去了遞歸的過程,只需要遍歷即可。
**2.**我自己用的遞歸。從第一個數開始壓棧,之後判斷這個數之後的符號,如果是加減直接去搜索後一位數,把這個數放在其後的位置就可以了。
如果是空格比較麻煩,這時候要用一個head和tail,分別表示他的首尾(用來處理連續的空格),然後每放進一個去,就讓前面的×10,100,1000……(看具體前面有多少個空格,這個長度可以用tail-head來計算)。
在寫這部分代碼的時候,有幾點我修改的比較多:
1.在什麼時候改變point和tail,讓他們指向下一個點進行修改。
2.在for循環的開始還是結尾去判斷是否已經搜索到底(最後寫在開頭);
3.關於head的位置,如果不寫那個while循環,他會每次都少一塊,所以通過while循環讓head移動到第一個後面是空格的位置。
4.在調試的時候,會出現多餘幾次的加和(其實對結果沒啥影響,就是多運行了幾次),所以我就在最後加了一個a[n]!=0,其實也沒啥用。
5.對tail、point和head的移動處理,我也是邊試邊寫的,過程的話還是自己畫畫草圖吧。
其實題也不算特別特別難(往往做完之後都這麼覺得),還是對遞歸回去各個數的改變太不熟悉了……一定多練題!!(大概)
ps:xdoj上反正提交是不給評判,管他的呢,反正自己有收穫,oj算個xxxxx……
ps2:第二天試了一下都能AC,兩個代碼都可以
代碼是遞歸思路寫的,先附上自己的代(亂)碼:
#include<stdio.h>
int a[20]={
0};
int head=1,tail=1;
int point=1;
int n;
int ans=0;
int main()
{
void dfs(int);
scanf("%d",&n);
a[1]=1;
dfs(1);
printf("%d",ans);
}
void dfs(int point)
{
int i,j;
for(i=1;i<=3;i++)
{
if(point==n)
break;
if(i==1)//此處爲+
{
point++;
a[point]=point;
tail=point;
head=tail;
dfs(point);//在這裏遞歸
a[point]=0;//這一部分是用來進行改變的
point--;
tail--;
if(head>tail)
head=tail;
continue;
}
if(i==2)//這裏是- ,和+基本一樣
{
point++;
a[point]=-point;
tail=point;
head=tail;
dfs(point);
a[point]=0;
point--;
tail--;
if(head>tail)
head=tail;
continue;
}
if(i==3)//這裏是空格,最難寫的地方
{
point++;
tail=point;
int lenth=1;
while(a[head-1]>=10||a[head-1]<=-10)//這是用來找第一個空格位置的,把head指過去
head--;
for(j=tail;j>=head;j--)//分正負進行討論
{
if(a[head]<0)
a[j]=-j*lenth;
if(a[head]>0)
a[j]=j*lenth;
lenth*=10;
}
dfs(point);
a[point]=0;
point--;
tail--;
if(head>tail)//這個處理突發奇想,防止head在tail後面
head=tail;
continue;
}
}
int sum=0;
for(j=1;j<=n;j++)
sum+=a[j];
if(sum==0&&a[n]!=0)//其實第二個沒啥用,是自己代碼爛了,打個補丁
ans++;
}
代碼有不好或者繞彎路的地方太正常了,我還只是個剛學c語言的大一弱雞,求放過~
另一種非遞歸轉三進制的方法有室友寫了,我就不再整活了,放一下:
億點感慨:
從下午七點寫到晚上1點,雖然不難吧但是對於不熟練的我真的是瘋狂折磨。在調試中度過一晚上,不過還好,至少學到東西了吧(而且有人陪着寫也沒那麼累)。而且,竟然有人看我博客?本來是寫了給自己看的,結果不知道哪位大聰明找到這裏來了(HAHAHA~)
ps3:這算不算dfs?我也不是很清楚😂,叫什麼的吧反正是遞歸就完事了(手動狗頭)