HL第三次考試

這次…怎麼說呢,快倒數了,但獲得了一個定理:暴力可能不會TLE,會MLE,會更慘,暴力優化多好都是0分…不虧不虧


##第一題
某位蒟蒻帶着n個山楂(cha)路過,碰見m個大佬,每個大佬都會敲詐他手中一半的山楂(cha),向下取整,並因爲可憐他還他一個,問到最後還有幾個山楂(cha)
數據範圍:n<=1*107,M<=2*109

簡化:給定一個數n,經過m次操作後還剩多少,操作爲除2加一,除法向下取整,也就是去掉小數部分

TIPS:假如只這樣的話,根據數據會T掉部分,所以要加上優化
因爲m的範圍比n大得多,所以到後面n的值就會變成2或3,並不斷執行,這樣會造成很多的重複操作,所以要特判一下

#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
	freopen("station.in","r",stdin);
	freopen("station.out","w",stdout);
	cin>>m>>n;
	for (int i=1;i<=n;i++)
	  {
	  	m-=m/2;
		m++;
		if (m==2||m==3)//特判
		  break; 
	  } 
	cout<<m<<endl;
	return 0;
}

##第二題
要跳n級樓梯,跳到偶數級時,可以選擇跳2級或3級;跳到奇數級時,可以選擇跳1級或,4級問跳n級的方案數,初始爲0級(偶數級)
由於計算出來的數可能過大,所以要對1*10^9+7取模

遞推,很樸素

代碼實現,對1*10^9+9取模,很樸素

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1000000007;
int n;
int a[50001000];
int main()
{
	freopen("stairs.in","r",stdin);
	freopen("stairs.out","w",stdout);
	cin>>n;
	a[0]=1;
	a[1]=0;
	for (int i=0;i<=n;i++)
	  if (i%2==0)
	    a[i+2]=(a[i+2]+a[i])%MAXN,a[i+3]=(a[i+3]+a[i])%MAXN;
	  else
	    a[i+1]=(a[i+1]+a[i])%MAXN,a[i+4]=(a[i+4]+a[i])%MAXN;
	cout<<a[n]<<endl;
	return 0;
} 

##第三題
有一隻貓,它的基因由三種字符’c’,‘a’,‘t’組成,每過一個單位時間,就會複製一遍基因,並在中間加上t-1個’a’(t爲過了幾個單位時間),問第i位的基因是什麼
大致如此
當t=1,爲"cat"
當t=2,爲"cat a cat"
當t=3,爲"catacat aa catacat"

分治題,很容易得出t=n時的基因數量爲f[n]=f[n-1]*2+(t-1) (f[1]=3),也就可以對那一串基因進行遞歸求解
也把基因分爲以上三種狀態,黑色的前半部分,紅色的中間一串’a’,藍色的後半部分
假如遞歸到中間的一串’a’那麼就直接輸出’a’,結束,美滋滋
因爲後半部分等於前半部分,所以如果遞歸到後半部分字母時就等於等量代換到前面半部分的字母,那麼就再次對前半部分進行遞歸

代碼片找不到了,所以也就將就着,想要看代碼片參照一位大佬的博客:點擊這裏
##第四題
你要分m個果子,現在有n個人,保證每人都有果子,有多少種分法
注意:假如有2人3果,1 2和2 1是同一種方案

因爲要保證每個人都有果子,所以先每個人給一個果子,再進行遞歸

直接給出代碼片

#include<bits/stdc++.h>
using namespace std;
int n,m;
inline int dfs(int x,int y)//x個果子分給y個人的方案數
{
	if (x<=1||y<=1)//果子只有一個或人只有一個
	  return 1;//只能有一個方案數
	else
	  if (x<y)//果子比人少
	    return dfs(x,x);//最多隻能分給x個人,所以和x人的方案數一樣
	  else 
	    if (x==y)//果子和人一樣
	      return dfs(x,x-1)+1;//讓一個人不拿就會變成人數差1的方案,否則方案數多了一個	    
	    else//果子比人多
	      return dfs(x,y-1)+dfs(x-y,y);//讓一個人不拿或每人拿一個
}
int main()
{
	freopen("monkey.in","r",stdin);
	freopen("monkey.out","w",stdout);
	cin>>n>>m;
	n-=m;//每人先給一個
	cout<<dfs(n,m)<<endl; 
	return 0;
} 

最後一題麼,emmmmm,是一道求區間最值問題,要用RMQ算法,至今還不知道怎麼做,所以就不發了哈哈


這次的博客正式結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章