題目如下
這道題看似很簡單,其實還是得觀察一下,要不然就會…
話不多說回到題目,這個題的坑就在于當A,B,C
三個產值相同的時候,再怎么變還是之前的產值,或者也可以通過另外一種方法理解:
通過一個案例來舉例:
可以明顯的看到,隨便一個樣例在經過N
次變化后總會相同
仔細分析,通過這個圖得知每次兩個產值之間的差值可以近似的看為是之前差值的一半,直到N
次之后差值相同,那么N
怎么求呢?
根據我們題目的信息:
- 對于 30% 的評測用例,1≤T≤100,1≤A,B,C,K≤105
- 對于 100%的評測用例,1≤T≤105,1≤A,B,C,K≤109
K最大會到109,每次除以2
,記差值為d
最大為109 ,那么就有 (d = 2x)->
x= logd <=
log1e9
#include<iostream>
#include<algorithm>
#include<cmath>
#include<climits>
using namespace std;
void solve(){cout << (int)log2(1e9); // 輸出 29(直接取整)cout << ceil(log2(1e9)); // 輸出 30(向上取整)
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;while(T--){solve();}return 0;
}
通過一個小小的程序,可以得到如果K向下取整得到29,向上取整得到30,取最大K等于30
,所以題目要求給的 K<=109 完全就是誘導(全都是紙老虎),實際根本用不了這么多,這也是超時這么多案例的主要原因,注意!!!!
由于 / 2 是 整數除法(向下取整),每次計算都會 損失精度。我們在這里行行好,給K
的值提升到50
AC代碼:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<climits>
using namespace std;
void solve(){int a,b,c,k;int a1,b1,c1;cin>>a>>b>>c>>k;int i=0;k=min(50,k);while(k--){i++;a1=(b+c)/2;b1=(a+c)/2;c1=(a+b)/2;a=a1,b=b1,c=c1;}cout<<a<<" "<<b<<" "<<c<<'\n';
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T;cin>>T;while(T--){solve();}return 0;
}
也可以直接三個產值相等的時候跳出循環
#include<iostream>
#include<algorithm>
#include<cmath>
#include<climits>
using namespace std;
void solve(){int a,b,c,k;int a1,b1,c1;cin>>a>>b>>c>>k;int i=0;while(k--){i++;a1=(b+c)/2;b1=(a+c)/2;c1=(a+b)/2;a=a1,b=b1,c=c1;if(a==b&&a==c&&b==c) break;}cout<<a<<" "<<b<<" "<<c<<'\n';
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T;cin>>T;while(T--){solve();}return 0;
}
實測第二個寫法跑的速度快一點,穩妥一點