https://ac.nowcoder.com/acm/contest/5678
A、拯救咕咕咕之史萊姆
鏈接:https://ac.nowcoder.com/acm/contest/5678/A
來源:牛客網
信鴿王國有一位美麗的公主,被可惡的巫師囚禁在了城堡裏,你是一位傾慕公主的勇者,準備去解救她。你來到了城堡外,發現有一隻醜陋的史萊姆阻擋了你的去路,向你索要進堡費,你囊中羞澀,並不想給錢,於是你給它撒了“洞洞索命粉末”!
洞洞索命粉末:被撒此粉末它的身上就會出現一個大洞,從中毒的第二天開始,大洞每天早上會分裂出一個小洞,小洞在出現後的第四天會長成大洞(並開始分裂),每個洞在每天下午會減少它 3 點 HP,HP 爲 0 時它就會死去。史萊姆很聰明,如果他意識到自己第二天就會死去,他就會向你求饒,讓開道路。
PS:你從小道消息得知公主就快要餓死了,所以你要趕在 5 天之內進入城堡,如果 5 天之後史萊姆還沒有向你求饒,那你只能氪金了。
輸入描述:
測試輸入包含若干測試用例,每個測試用例佔一行,包含一個整數 n(long long範圍內),表示史萊姆的初始 HP 值,當 n 爲 0 時輸入結束。
輸出描述:
對每個測試用例,如果 5 天之內(包括第 5 天)史萊姆向你求饒,那就輸出“AOLIGEI!”,否則,輸出“DAAAAAMN!”,沒有雙引號。
示例1
輸入
複製 5 73 77 0
5 73 77 0
輸出
複製 AOLIGEI! AOLIGEI! DAAAAAMN!
AOLIGEI! AOLIGEI! DAAAAAMN!
思路:類似生兔子的dp,不過方便點的無腦方法就是觀察樣例一個個試過去。在73-77中挑一個數。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5;
typedef long long LL;
LL dp[maxn];
int main(void)
{
LL n;
while(cin>>n&&n!=0)
{
//LL sum=18;
if(n<=75) cout<<"AOLIGEI!"<<endl;
else cout<<"DAAAAAMN!"<<endl;
}
return 0;
}
E-無敵阿姨
鏈接:https://ac.nowcoder.com/acm/contest/5678/E
來源:牛客網
X 學校最近計劃安排宿管阿姨幫每個宿舍的人曬被子,爲了提高效率僱傭了一個無敵阿姨,已知無敵阿姨曬被子的方式如下:
1、進入當前有被子的最低層拿儘可能多的被子,每拿走 1 牀被子體力值減 1;
2、如果當前層的被子被拿完且此時的體力值大於 k ,消耗 k 點體力值進入到上層樓;
3、在當前層拿儘可能多的被子,每拿走 1 牀被子體力值減 1 ,重複步驟 2;
4、如果體力耗盡或者此時的體力小於等於 k ,將被子拿出去放到晾衣架,體力恢復爲初始體力值;
PS:阿姨在沒有取得被子之前上樓不消耗體力。
先給出樓的層數 n ,阿姨的體力值 m ,阿姨抱着被子上樓的體力消耗值 k ,每層的被子數 aia_iai ,問阿姨需要幾次能夠把所有被子拿出去?
輸入描述:
輸入包含多組數據,第一行包含一個數字 T(1≤T≤10)T(1 \le T \le 10)T(1≤T≤10),表示測試數據組數。接下來是T組數據, 每組數據第一行爲三個整數 n,m,k(1≤n,m,k≤100)n,m,k(1 \le n,m,k \le 100)n,m,k(1≤n,m,k≤100)分別表示樓的層數,阿姨的體力值以及抱着被子上樓的體力消耗值。 第二行 n 個整數 a1,a2,a3,...,an(1≤ai≤100)a_1,a_2,a_3,...,a_n(1 \le a_i \le 100)a1,a2,a3,...,an(1≤ai≤100) 表示每層的被子數。
輸出描述:
每組數據輸出包含一個整數,表示阿姨把所有的被子都拿出去需要的次數。
示例1
輸入
複製 1 4 5 1 1 1 2 4
1 4 5 1 1 1 2 4
輸出
複製 3
3
說明
第一次阿姨先從第一層拿一牀被子,再上到第二層拿1牀被子,再上到第三層拿一牀被子,其中拿被子消耗體力爲3,上樓消耗體力爲2;第二次阿姨先從第三層拿一牀被子,再上到第四層拿三牀被子,其中拿被子消耗體力爲4,上樓消耗體力爲1;第三次阿姨直接從第四層拿一牀被子消耗體力爲1,全部爲拿被子消耗的體力。
思路:模擬的思路一直比較弱,需要藉助一些方法來模擬,比如雙指針,這裏我藉助了雙端隊列模擬。在某場cfdiv4中我看到一個鴿鴿二道或者三道都是deque模擬的。deque用來做模擬題應該會比較方便
#include<iostream>
#include<vector>
#include<queue>
#include<deque>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5;
typedef long long LL;
int main(void)
{
LL t;cin>>t;
while(t--)
{
LL n,m,k;cin>>n>>m>>k;
LL res=0;deque<LL> a;
for(LL i=0;i<n;i++) { LL x;cin>>x;a.push_back(x);}
LL p=m;
LL floor=0;
while(a.size()>0&&a.size()<=n)
{
// cout<<"a.size()="<<a.size()<<endl;
LL t=a[0];
a[0]=a[0]-p;
p-=t;
if(a[0]<=0) a.pop_front(),floor++;
if(p<k||floor==n) res++,p=m;
else if(p>=k) p-=k;
// cout<<"res="<<res<<endl;
}
cout<<res<<endl;
}
return 0;
}
G-校車
鏈接:https://ac.nowcoder.com/acm/contest/5678/G
來源:牛客網
西安郵電大學有一輛從老校區到新校區的校車,總共有 n 個學生乘坐校車,在 aia_{i}ai 站上車,在 bib_{i}bi 站下車。學校打算去除一部分不必要的站點,請問需要保留多少站點,需要安排多少個座位?
輸入描述:
輸入 T 組數據 (1≤T≤10)(1 \le T \le 10)(1≤T≤10) 輸入 n(1≤n≤105)n(1 \le n \le 10^{5})n(1≤n≤105) 輸入 n 組 ai,bi(1≤ai,bi≤109)a_{i},b_{i}(1 \le a_{i},b_{i} \le 10^{9})ai,bi(1≤ai,bi≤109)
輸出描述:
輸出保留站點數,座位數。
示例1
輸入
複製 1 3 1 2 1 3 2 4
1 3 1 2 1 3 2 4
輸出
複製 4 2
4 2
思路:對一段數軸進行差分,需要的座位是累加差分的最大值,統計有多少個不重站點就是答案。學生的人數比站點的範圍少很多,要離散化。
離散化板子:爲了方便debug以後把離散化的板子裏面的二分改成STL的
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 3e5+10;
LL n, m;
LL a[maxn], b[maxn],c[maxn];
vector<LL> v;
LL find(LL x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin();
}
int main(void)
{
LL t;cin>>t;
while(t--)
{
v.clear();//////多組清空
LL n;cin>>n;
for(LL i=1;i<=n+10;i++) a[i]=b[i]=0;
for(LL i=0;i<n;i++)
{
cin>>a[i]>>b[i];
v.push_back(a[i]);v.push_back(b[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(LL i=0;i<v.size();i++) c[i]=0;
for(LL i=0;i<n;i++)
{
c[find(a[i])]++;
c[find(b[i])]--;
}
LL cnt=c[0], res=cnt;
for(LL i=1;i<v.size();i++)
{
cnt+=c[i];
res=max(res,cnt);
}
cout<<v.size()<<' '<<res<<endl;
}
return 0;
}
H-中位因數
鏈接:https://ac.nowcoder.com/acm/contest/5678/H
來源:牛客網
題目描述
給出函數的定義如下:
f(x)是所有能夠整除 x 的數(包含 1 和 x )中的中位數向下取整的大小,
g(x)=∑i=1xf(i)g(x)=\sum_{i = 1}^{x}{f(i)}g(x)=∑i=1xf(i)
輸入描述:
輸入包含多組數據,第一行爲一個數字 T(1≤T≤10)T(1 \le T \le 10)T(1≤T≤10) ,表示測試數據組數。 接下來是 T 組數據,每組數據爲一行,包含一個整數 x(1≤x≤1000000)x(1 \le x \le1000000)x(1≤x≤1000000)
輸出描述:
每組數據輸出包含一個整數,表示 g(x) 的值,結果要求對 1e9+7 取模。
示例1
輸入
複製 3 1 2 3
3 1 2 3
輸出
複製 1 2 4
1 2 4
說明
能夠整除 1 的數字有 1 ,故 f(1)=1; 能夠整除 2 的數字有 1,2 所以中位數爲⌊1+22⌋=1\lfloor \frac{1+2}{2} \rfloor = 1⌊21+2⌋=1,故 f(2) = 1; 能夠整除 3 的數字有 1,3 ,所以中位數爲1+32=2\frac{1+3}{2}=221+3=2 ,故 f(3) = 2; 從而得出 g(1) = 1,g(2) = 2,g(3) = 4 。
示例2
輸入
複製 1 1000000
1 1000000
輸出
複製 677045223
677045223
思路:對一個數n來說,他的因子會在根號n兩側,那麼根號n左邊有多少個,根號n右邊就有多少個。那麼題目的中位因數的意思是讓我們找最靠近根號n的兩個。(當然可能==根號n的情況)
那麼我們進行枚舉,假設一個數爲x,它會有很多因子,比如有一組配對因子是i,j(我們假設i<=j).
那麼先令a[x]=(i+j)/2,使(i+j)/2是x的中位因數,之後不斷更新,更新到最後a[x]裏面存的是i和j最接近的一對因數的中位因數。
當時沒搞懂這個循環,記錄一下:類似桶,a[i*j==x],x的因數有i,j,且默認i<=j,然後枚舉更新x的中位因數
比如16,剛開始a[16==1*16]=8;到後面會更新到a[16==4*4]==4;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,mod=1e9+7,M=1e6;
int ans[N],a[N],n,t;
int main(){
memset(a,0x7f,sizeof(a));
for(int i=1;i<=1000;i++)
for(int j=i;i*j<=M;j++)
{
{
a[i*j]=min(a[i*j],(i+j)/2);//類似桶,a[i*j==x],x的因數有i,j,且默認i<=j,然後枚舉更新x的中位因數
}
}
for(int i=1;i<=M;i++) ans[i]=(ans[i-1]+a[i])%mod;
cin>>t;
while(t--){
cin>>n;
cout<<ans[n]<<endl;
}
return 0;
}