A. Yogurt Sale
买一瓶酸奶要 a 元,买两瓶酸奶只要 b 元
要买 n 瓶奶,最少要多少钱
先两个两个买,2*a和b哪个便宜就买哪个,最后还差一瓶就买a
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--){
int n,a,b;
cin>>n>>a>>b;
int ans=0;
while(n>=2){
if(a*2<=b){
ans+=2*a;
}else ans+=b;
n-=2;
}
if(n)ans+=a;
cout<<ans<<endl;
}
return 0;
}
B. Progressive Square
用所给的 b 数组,是否能组成n*n的矩阵,右边的比左边大d,下面比上面大c
因为一直在变大放数,所以给b排序然后模拟,先放第一列,然后从第一列扩展到右边。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
map<int,int>f;
int n,c,d;
cin>>n>>c>>d;
int b[n*n+1];
for(int i=1;i<=n*n;++i)cin>>b[i],f[b[i]]++;
sort(b+1,b+1+n*n);
//往下+c,往右+d
int row[n];
for(int i=1;i<=n;++i){
if(i==1){
row[i]=b[i];
f[b[i]]--;
}else{
row[i]=row[i-1]+c;
if(f[row[i]]){
f[row[i]]--;
}else{
cout<<"NO"<<endl;
return ;
}
}
}
int col[n];
for(int i=1;i<=n;++i){
for(int j=2;j<=n;++j){
col[j]=row[i]+d*(j-1);
if(f[col[j]]){
f[col[j]]--;
}else{
cout<<"NO"<<endl;
return;
}
}
}
cout<<"YES"<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
C. Inhabitant of the Deep Sea
a 数组是 n 个船拥有的耐久,你可以进行 k 次攻击,先打头,然后打尾,直到把船耐久打到0结束。
问最多可以打沉几艘。
因为先攻击头部,所以如果 k 是奇数,头打 k/2+1 次,尾打 k/2 次
偶数均 k/2 次。
然后用 deque 模拟攻击,注意不能一点一点耐久打,直接整个去匹配。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int n,k;
cin>>n>>k;
deque<int>q;
for(int i=1;i<=n;++i){
int tmp;
cin>>tmp;
q.push_back(tmp);
}
//攻击k次
int ans=0;
int head=k/2,tail=k/2;
if(k&1)head++;
while(head and q.size()){
if(head>=q[0]){
head-=q[0];
q.pop_front();
ans++;
}else{
q[0]-=head;
head=0;
}
}
while(tail and q.size()){
if(tail>=q[q.size()-1]){
tail-=q[q.size()-1];
q.pop_back();
ans++;
}else{
q[q.size()-1]-=tail;
tail=0;
}
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
D. Inaccurate Subsequence Search
a数组中长度为m的连续子数组c,若c中有至少k个 和 b数组中的相等 答案+1
第一个数组 [1,m] 和下一个数组 [2,m+1] 只有左右端点变化了,不需要全部修改,只要改两端。
然后模拟一遍就可以了,注意solve里面初始化要针对性初始化,不然会超时。
t=1e4,solve中 1~1e6初始化就会超时,要针对所给的 n 和 m 需要的部分初始化。
// LUOGU_RID: 155159959
#include <bits/stdc++.h>
using namespace std;
const int MAX=1e6+5;
void solve(){
//a数组中长度为m的连续子数组c,
//若c中有至少k个 和 b数组中的相等 答案+1
int n,m,k;
cin>>n>>m>>k;
int a[n+1];
for(int i=1;i<=n;++i)cin>>a[i];
int b[m+1];
for(int i=1;i<=m;++i)cin>>b[i];
int now[MAX],need[MAX];
for(int i=1;i<=n;++i){
need[a[i]]=now[a[i]]=0;
}
for(int i=1;i<=m;++i){
need[b[i]]=now[b[i]]=0;
}
for(int i=1;i<=m;++i){
need[b[i]]++;
}
int cmped=0;
for(int i=1;i<=m;++i){
if(need[a[i]] and now[a[i]]<need[a[i]]){
cmped++;
}
now[a[i]]++;
}
int l=1,r=m;
int ans=0;
if(cmped>=k)ans++;
while(r<n){
if(need[a[l]] and now[a[l]]<=need[a[l]]){
cmped--;
}
now[a[l]]--;
l++,r++;
if(need[a[r]] and now[a[r]]<need[a[r]]){
cmped++;
}
now[a[r]]++;
if(cmped>=k)ans++;
}
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}