#10005. 「一本通 1.1 練習 1」數列極差
阿新 • • 發佈:2018-12-21
【題目描述】
佳佳的老師在黑板上寫了一個由 n個正整陣列成的數列,要求佳佳進行如下操作:每次擦去其中的兩個數 a 和 b,然後在數列中加入一個數 a×b+1,如此下去直至黑板上剩下一個數為止,在所有按這種操作方式最後得到的數中,最大的為 max,最小的為 min, 則該數列的極差定義為 M=max−min。
由於佳佳忙於準備期末考試,現請你幫助他,對於給定的數列,計算出相應的極差 M。
【輸入格式】
第一行為一個正整數 n 表示正整數序列的長度;
在接下來的 n 行中,每行輸入一個正整數。
接下來的一行有一個 0,表示資料結束。
【輸出格式】
輸出只有一行,為相應的極差 M。
【樣例輸入】
3
1
2
3
0
【樣例輸出】
2
【資料範圍與提示】
對於全部資料,0≤n≤50000,保證所有資料計算均在 32位有符號整數範圍內。
思路:看到這道題目真的覺得我在loj做了這麼久的貪心題,看上去最和藹可親的一題了。思路很簡單,定義一個a陣列,為輸入的陣列,然後定義一個b陣列,為複製a陣列的陣列,因為我們要用最大值和最小值來相減,所以我們必然要定義兩個陣列來儲存兩個量。重點就是排序,一個數組從小到大排序,一個數組從大到小排序。因為題目說了,每進行一次,就會減少一個數,所以我們在每一次減少的時候都必須要重新排序。才能使得之後的數都是我們想要的順序,這樣才能方便輸出。大概寫了這麼多之後,歸根到底就是幾個字: 定義陣列->排序->減數->排序->輸出。接下來就看程式碼吧,我會放出三個程式碼:第一個是把後一個數變為要更換的是,第二個是把前一個數變為要更換的數,第三個就是分兩個迴圈分別求出最大值和最小值。
【程式碼一】
/* 題目解釋, 求一堆數裡面的兩兩組合消滅之後的最大值和最小值 輸出最大值與最小值的差值 然後題目說有一個結束符0,千萬不要被這個結束符給迷惑了 然後就用了超級複雜的多組資料 其實就是簡單的輸入n+1個數字,因為題目說了:“ 在接下來的n行中,每行輸入一個正整數。”(真香——) */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int read()//日常快讀 { char c=getchar(); int x=0,f=1; while(c<48 || c>57) { if(c=='-') f=-1; c=getchar(); } while(c>=48 && c<=57) { x=x*10+c-48; c=getchar(); } return x*f; } bool cmpmin(int n1,int n2) //min是小的意思,所以這個函式就是從小到大排序 { return n1<n2; } bool cmpmax(int n1,int n2) //max是大的意思,所以這個函式就是從大到小排序 { return n1>n2; } int a[51000];//原始輸入陣列 int b[51000];//複製陣列 int main() { int n; n=read(); for(int i=1;i<=n+1;i++) { a[i]=read(); b[i]=a[i];//複製 } sort(a+1,a+n+1,cmpmin);//a陣列從小到大排序 sort(b+1,b+n+1,cmpmax);//b陣列從大到小排序 for(int i=1;i<n;i++) //因為要求的是i+1所以如果是到n的話,那i+1就是結束符0 { a[i+1]=a[i]*a[i+1]+1; /* 我把下一個數更新為當前這個數與下一個數的乘積+1 其實就是題目要求的 */ b[i+1]=b[i]*b[i+1]+1; /* 我把下一個數更新為當前這個數與下一個數的乘積+1 其實就是題目要求的, 注意:b陣列求出來的值應該是與a陣列求出來的值不一樣 因為b陣列是從大到小排序,a陣列是從小到大 */ sort(a+i+1,a+n+1,cmpmin); /* 這一步就是a陣列在經過改變之後的從小到大的排序 剛開始就是這裡亂了, 注意一下:我們的a[i]已經不存在了,因為我們把a[i]和a[i+1] 合併成為一個了,所以我們這個時候是從a+i+1開始排序 而不是有a+1開始,所以有的人在除錯的時候可能會亂 然後我在強調一下 這個是從小到大排序,也就是說他的最後一個是最大的 */ sort(b+i+1,b+n+1,cmpmax); /* 這一步就是b陣列在經過改變之後的從小到大的排序 注意一下:我們的b[i]已經不存在了,因為我們把b[i]和b[i+1] 合併成為一個了,所以我們這個時候是從b+i+1開始排序 而不是有b+1開始, 然後我在強調一下 這個是從大到小排序,也就是說他的最後一個是最小的 */ } printf("%d\n",a[n]-b[n]); /* 我相信我上面講了a陣列的最後一個最大 b陣列的最後一個最小 所以他們的最大差值就是 a陣列的最後一個-b陣列的最後一個 */ return 0; }
【程式碼二】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
char c=getchar();
int x=0,f=1;
while(c<48 || c>57)
{
if(c=='-') f=-1;
c=getchar();
}
while(c>=48 && c<=57)
{
x=x*10+c-48;
c=getchar();
}
return x*f;
}
bool cmpmin(int n1,int n2)
{
return n1<n2;
}
bool cmpmax(int n1,int n2)
{
return n1>n2;
}
int a[51000];
int b[51000];
int main()
{
int n; n=read();
for(int i=1;i<=n+1;i++)
{
a[i]=read();
b[i]=a[i];
}
for(int i=n;i>=2;i--)
{
sort(a+1,a+i+1,cmpmin);
sort(b+1,b+i+1,cmpmax);
a[i-1]=a[i]*a[i-1]+1;
b[i-1]=b[i]*b[i-1]+1;
}
printf("%d\n",b[1]-a[1]);
return 0;
}
【程式碼三】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
char c=getchar();
int x=0,f=1;
while(c<48 || c>57)
{
if(c=='-') f=-1;
c=getchar();
}
while(c>=48 && c<=57)
{
x=x*10+c-48;
c=getchar();
}
return x*f;
}
bool cmpmin(int n1,int n2)
{
return n1<n2;
}
bool cmpmax(int n1,int n2)
{
return n1>n2;
}
int a[51000];
int b[51000];
int main()
{
int n; n=read();
for(int i=1;i<=n+1;i++)
{
a[i]=read();
b[i]=a[i];
}
int t=n;
int ans1,ans2;
sort(a+1,a+n+1,cmpmax);
while(t>1)
{
int tmp=a[t]*a[t-1]+1;
t--;
a[t]=tmp;
sort(a+1,a+t+1,cmpmax);
}
ans1=a[t];
sort(b+1,b+n+1,cmpmin);
t=n;
while(t>1)
{
int tmp=b[t]*b[t-1]+1;
t--;
b[t]=tmp;
sort(b+1,b+t+1,cmpmin);
}
ans2=b[t];
printf("%d",ans1-ans2);
return 0;
}