複習時食用,會比較簡略。
目錄
#10005. 「一本通 1.1 練習 1」數列極差
題目大意
一個由n個正整數組成的數列,每次擦去其中的兩個數a和b。
然後在數列中加入一個數a*b+1,直至剩下一個數爲止。
按這種操作方式最後得到的數中,最大的爲max,最小的爲min。
該數列的極差定義爲M=max-min。
請對於給定的數列計算出相應的極差M。
對於全部數據,0<=n<=50000,保證所有數據計算均在32位有符號整數範圍內。
題目分析
surprise!神奇的規律!
要得到max每次就擦掉最大的兩個,要得到min每次就擦掉最小的兩個。
進行多次試驗尋找普遍規律。
肯定有什麼證明方法,看我腦筋急轉彎。還是不會。
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,nn,x,a[50010],b[50010];
int cmp(int x,int y) { return x>y; }
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
a[i]=b[i]=x;
}
scanf("%d",&x);
sort(a+1,a+1+n,cmp); nn=n;
for(int i=1;i<=n-1;i++)//每次檫最大
{
a[1]=a[1]*a[2]+1;
a[2]=a[nn]; nn--;
sort(a+1,a+1+nn,cmp);
}
sort(b+1,b+1+n); nn=n;
for(int i=1;i<=n-1;i++)//每次擦最小
{
b[1]=b[1]*b[2]+1;
b[2]=b[nn]; nn--;
sort(b+1,b+1+nn);
}
printf("%d",b[1]-a[1]);
return 0;
}
#10006. 「一本通 1.1 練習 2」數列分段
題目大意
給定的一個長度爲N的正整數數列A_i。
將其分成連續的若干段,使每段和不超過M,問最少能將其分成多少段。
對於20%的數據,有n<=10;
對於40%的數據,有n<=1000;
對於100%的數據,有n<=10^5,m<=10^9大於所有數的最大值。
題目分析
好水。
不懂就看代碼ba。
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int n,m; scanf("%d%d",&n,&m);
int s=0,ans=0;
for(int i=1;i<=n;i++)
{
int x; scanf("%d",&x); s+=x;
if(s>m) { ans++; s=x; }//超過了
}
if(s) ans++;
printf("%d",ans);
return 0;
}
#10007. 「一本通 1.1 練習 3」線段
題目大意
有n條線段,選取其中k條線段使這k條線段沒有重合部分,問k最大爲多少。
對於20%的數據,n<=10;
對於50%的數據,n<=10^3;
對於70%的數據,n<=10^5;
對於100%的數據,n<=10^6,0<=ai<bi<10^6。
題目分析
迴歸例題1、2???
一段時間改成了一條線段。
一樣要需要沒有重合。
報告完畢。
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{int a,b;}a[1000010];
int cmp(node x,node y) { return x.b<y.b; }
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].a,&a[i].b);
sort(a+1,a+1+n,cmp);
int ans=1,end=a[1].b;
for(int i=2;i<=n;i++)
{
if(a[i].a>=end)
{
ans++; end=a[i].b;
}
}
printf("%d",ans);
return 0;
}
#10008. 「一本通 1.1 練習 4」家庭作業
題目大意
每個作業完成時間都是一天,在規定的時間內交上來的話纔有學分。
找到一個完成作業的順序獲得最大學分。
對於20%的數據,n<=10^3;
對於40%的數據,n<=10^4;
對於60%的數據,n<=10^5;
對於100%的數據,n<=10^6,作業的完成期限均小於7*10^5
題目分析
迴歸例題5。
只要加一個小小小優化就好了。
而且這個優化很容易懂。
kk判斷i和i之前的時間是否被填滿,若已經填滿了就不要去找了。
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
bool f[700010],kk[700010];
struct node{int time,money;}a[1000010];
int cmp(node x,node y) { return x.money>y.money; }
int main()
{
int n; scanf("%d",&n);
memset(f,false,sizeof(f));
memset(kk,false,sizeof(kk));
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].time,&a[i].money);
sort(a+1,a+1+n,cmp);
int ans=0;
for(int i=1;i<=n;i++)
{
bool k=false;
for(int j=a[i].time;j>=1;j--)
{
if(kk[j]) break;
if(!f[j]) { f[j]=true; k=true; }
if(k) break;
}
if(k) ans+=a[i].money;
else kk[a[i].time]=true;
}
printf("%d",ans);
return 0;
}
#10009. 「一本通 1.1 練習 5」釣魚
題目大意
有n個釣魚湖,從左到右編號爲1,2,…,n。希望利用H個小時釣到更多的魚。
從1出發,向右走,可選擇在湖邊停留一定的時間釣魚,最後在某一個湖邊結束釣魚。
從第i個湖到第i+1個湖需要走5*T_i分鐘,測出在第i個湖停留,第一個5分鐘可以釣到F_i條魚,以後再釣5分鐘,釣到的魚量減少D_i,若減少後的魚量小於0,則魚量爲0。
沒有其他因素影響釣到期望數量的魚。求出最多能釣魚的數量。
對於100%的數據,2<=n<=100,1<=h<=20。
題目分析
釣個魚怎麼這麼多事。
枚舉最遠去到的魚塘的位置,範圍內的魚塘任你挑,當然是釣最多的啊。
很好懂的吧。好暴力啊。
我果然還是太辣雞了,如果魚的數量是負的就不要釣了,傻嗎還釣。
我纔不會告訴你我小測的時候就錯在這。
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
bool f=false;
int n,h,s,t[110],ans=0;
struct node{int a,b;}a[110],b[110];
int cmp(node x,node y) { return x.a>y.a; }
int main()
{
scanf("%d%d",&n,&h);
for(int i=1;i<=n;i++) scanf("%d",&a[i].a);
for(int i=1;i<=n;i++) scanf("%d",&a[i].b);
h*=12; t[1]=0; s=n;//12個五分鐘
for(int i=2;i<=n;i++)
{
int x; scanf("%d",&x);
t[i]=t[i-1]+x;//x個五分鐘
if(!f&&t[i]>=h) f=true,s=i-1;//s表示最遠能去到的魚塘
}
for(int ed=1;ed<=s;ed++)
{
for(int i=1;i<=ed;i++) b[i]=a[i];
int tt=h-t[ed],kk=0;
while(tt--)//實在是很暴力了
{
sort(b+1,b+1+ed,cmp);
if(b[1].a<=0) break;
kk+=b[1].a; b[1].a-=b[1].b;
}
ans=max(ans,kk);
}
printf("%d",ans);
return 0;
}
#10010. 「一本通 1.1 練習 6」糖果傳遞
這道題已經盡我的洪荒之力寫的詳細了!!!(個人覺得很明白了昂)