1.雷達裝置
題目連結:https://www.acwing.com/problem/content/114/
解決思路:我們所要找到的是雷達的最小數目,因此我們需要對每個小島進行大都分析
①求出能夠到達他的海岸線的範圍,通過d與y我們可以求出他的x軸上的覆蓋範圍,(l,r),然後按照區間的右端點排序。
②求出每個島的覆蓋範圍後,我們需要找出最少的使用雷達的數量,如果當前區間包括下一點的區間範圍,則直接跳過;如果當前區間不能包含下一個區間,則增加一個雷達數目,並且將雷達範圍更新為下一個雷達的區間。
例如下圖所示:只需要三個雷達即可
程式碼:
#include<iostream> #include<cmath> #include<cstdio> #include<algorithm> using namespace std; const int N=10101; struct node { double l,r; bool operator <(const node &t)const { return r<t.r; } }s[N]; int main() { int i,j,n,d,x,y; bool flag=false; scanf("%d%d",&n,&d); for(i=0;i<n;i++) { scanf("%d%d",&x,&y); if(y>d) flag=true; else { double len=sqrt(d*d-y*y); s[i].l=x-len;s[i].r=x+len;//計算每個島的區間 } } if(flag==true) { puts("-1"); } else { sort(s,s+n);//按照區間右端點排序 int cnt=0; double nowl=-1e20; for(i=0;i<n;i++) { if(nowl<s[i].l)//判斷當前取件是否有下一個區間的點 { cnt++; nowl=s[i].r;//更新區間 } } printf("%d\n",cnt); } return 0; }
2.付賬問題
題目連結:https://www.acwing.com/problem/content/1237/
解題思路:計算最小的方差,S是固定的,因此AVG也是固定的,只要每個人所掏的錢數越接近於AVG,那麼方差就會越小
①首先如果每個人的錢數都超過AVG,那麼方差就是0
②如果有的人可能錢包小於AVG,那麼不夠的錢應該分攤到那些錢包有剩餘的人那裡,因此,我們首先需要將每個人的錢進行從小到大排序,分別計算當前人數的平均值,看當前這個人的錢包是否足夠,不夠就掏出自己目前所有的錢,然後,到第二個人的時候需要掏的錢:(S-a[0])/(n-1),如果也不夠,也是掏出自己目前所有的錢,到第三個人的時候需要掏出:(S-a[0]-a[1])/(n-2)依次類推,算出最小方差,進而算出最小標準差,再保留4為小數。
程式碼:
#include<iostream> #include<cmath> #include<cstdio> #include<algorithm> using namespace std; const int N=500010; int n,a[N]; double s; int main() { int i,j; cin>>n>>s; for(i=0;i<n;i++) cin>>a[i]; sort(a,a+n); double ans=0,avg=s/n; for(i=0;i<n;i++) { double cur=s/(n-i); if(a[i]<cur) cur=a[i]; ans+=(cur-avg)*(cur-avg); s-=cur; } printf("%.4lf",sqrt(ans/n)); return 0; }
3.乘積最大
題目連結:https://www.acwing.com/problem/content/description/1241/
解題思路:雙指標演算法,根據K的奇偶分別計算
當K是偶數,結果非負,因為,如果負數是偶數個,負負得正,結果為非負;如果負數是奇數個,那就選偶數個絕對值最大的負數
k 如果是奇數個的話,
(1)所有的數字如果都是負數,那麼選出來的結果也一定都是負數
(2)否則的話,則一定至少有 1個非負數, 那麼我們將最大的數取出來, 此時要選的個數就是 k--,
# k-- 是偶數,那麼就又轉化為 k-- 是偶數的情況思考
程式碼:
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; typedef long long ll; int n,k; const int mod=1000000009; const int N=100010; int a[N]; int main() { int i,j; cin>>n>>k; for(i=0;i<n;i++) cin>>a[i]; sort(a,a+n); ll res=1,l=0,r=n-1; int sign=1; if(k%2) { res=a[r--]; k--; if(res<0) sign=-1; } while(k) { ll x=(ll)a[l]*a[l+1]; ll y=(ll)a[r]*a[r-1]; if(x*sign>y*sign) { res=x%mod*res%mod; l+=2; } else { res=y%mod*res%mod; r-=2; } k-=2; } printf("%lld",res); return 0; }