?? 程序競賽題解答.cpp
字號:
#if 0
C題 排 隊
【問題描述】
全班有N(2<=N<=45)個人排成一排,但因為高矮不齊,需要進行調整。調整的方法是,不調換左右次序,只讓若干人后退一步變為第2排,使第一排留下的人從左到右的身高按降序排列,即右邊的人不比左邊的人高。如果第2排的人還不按降序排列,則照此辦理,即再讓第2排的若干人后退一步變為第3排,這樣繼續下去,直到所有排的人都按身高從高到低排列。
調整中,你需要找出一種使第一排留下的人數盡可能多的調整方法,第二排若需要繼續調整,則也應使第二排留下的人數盡可能多,余類推。
【輸入】
輸入文件第一行為一個整數M,表示有M組測試數據。接下來的兩行為一組測試數據,每組測試數據的第一行為一個整數N,表示該組測試數據的人數;接下來的一行是這N個人的身高,以厘米為單位,且都為整數,每個數用空格隔開。
【輸出】
對于每組測試數據輸出應該是2行:
第一行:第一排留下的人數Man;
第二行:最后調整完共有幾排Low。(具體格式請嚴格按照樣例輸出進行)
【樣例輸入】
3
8
130 122 112 126 126 125 120 100
5
187 187 178 165 164
5
187 187 178 165 167
【樣例輸出】
Man=6
Low=2
Man=5
Low=1
Man=4
Low=2
#endif
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
FILE *fp;
char buf[40];
int i=0,j=1,n,s[40],index,mmax,mxy,col=0,tmp,mm,tmp1,tmp2,mmin,nn=0;
int Q[40],first=0,last=1;
bool ok=true,oo=true;
fp=fopen("dl.in","r");
fgets(buf,40,fp);
sscanf(buf,"%d",&n);
memset(s,0,40*sizeof(int));
fgets(buf,40,fp);
while(buf[i]!='\n') //讀取數據 (方法煩啦)
{
if(buf[i]!=' ') {s[j]=s[j]*10;s[j]=s[j]+(buf[i]-'0');}
else j++;
i++;
}
for(i=1;i<=n;i++) cout<<s[i]<<" ";
cout<<endl;
begin:
mmax=0;mmin=0;
if(ok) {index=1;first=last=1;Q[last++]=index;ok=false;}
mmin++;
while(first<last)
{
tmp=s[index];
for(i=index;i>1;i--)
{
if(s[i]>=tmp) {mmin++;tmp=s[i];}
else
{
if(index==1) Q[last++]=i;
}
}
tmp=s[index];
for(i=index+1;i<=n;i++)
{
if(s[i]<=tmp) {mmin++;tmp=s[i];}
else
{
if(index==1) Q[last++]=i;
}
}
if(mmax<mmin) {mmax=mmin;mxy=index;}
index=Q[++first];mmin=0;mmin++;
}
if(oo) {cout<<"Man= "<<mmax<<endl;oo=false;}
col++;
tmp=Q[mxy];
for(i=mxy-1;i>1;i--) if(Q[i]>tmp) {tmp=Q[i];mm=i;}
tmp1=tmp2=Q[mxy];
for(i=1;i<=last-1 && i!=mxy;i++)
{
if(i>mxy && Q[i]<tmp1) {s[i]=Q[i];tmp1=Q[i];nn++;}
if(i>=mm && i<mxy && Q[i]>tmp2) {s[i]=Q[i];nn++;}
}
if(last>2) {n=nn;ok=true;goto begin;}
cout<<"Low= "<<col<<endl;
fclose(fp);
system("PAUSE");
return EXIT_SUCCESS;
}
//另外的方法 可以從后面開始 每個數據編號 規則是此數要>=后面的數 且此數的編號是最大
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -