A. Kids Seating
思路:非常easy的构造 从后往前即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
for(int i=4*n,cnt=1;cnt<=n;i-=2,cnt++){
cout<<i<<" ";
}
puts("");
}
return 0;
}
B - Saving the City
题意:排地雷
思路:我们只需要从前往后遍历一边 如果相差的距离安地雷的花费小于 直接引爆 那么我们安地雷 否则我们直接引爆
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=1e3+10;
int a[N][N];
int dx[4]={0,-1,0};
int dy[4]={-1,0,1};
int main(){
int T;
cin>>T;
while(T--){
int x,y;
cin>>x>>y;
string a;
cin>>a;
int sum=0,L=0;
for(int i=0;i<a.size();i++){
if(a[i]=='1'){
if(!L){
sum+=x;
}
else if(L+1<i+1){
if((i-L)*y<x)
sum+=(i-L)*y;
else sum+=x;
}
L=i+1;
}
}
cout<<sum<<endl;
}
return 0;
}
C. The Delivery Dilemma
题意:买菜 2种方式到家 快递 和 自己拿 花费分别为a数组和b数组
a数组为并发 最大时间为最大的那个 而 自己拿菜为累加
思路:当ax<ay时 如果我们选择了ay 那么所有小于ay的我们都可以发快递
故我们可以进行排序 按照a的大小 pair捆绑a和b
sum为所有自己拿回家的b总和 当sum+b>a时 后续全部按照快递方式
最终结果 sum与a取最大值
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=2e5+10;
pair<int,int>a[N];
int main(){
int T;
cin>>T;
while(T--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].first);
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i].second);
}
sort(a+1,a+1+n);
int ans=0;
while(ans+a[n].second<a[n].first){
ans+=a[n].second;
n--;
}
cout<<max(ans,a[n].first)<<endl;
}
return 0;
}
D - Extreme Subtraction
思路:muwu一语便点醒我这个菜鸡 如果a[i]>a[i+1]那么就从左边拿
我们从1到n从左至右遍历整个数组 将所有的a[i]>a[i+1]变为a[i] 并将这个值累加到sum中
即将他构成一个从右到左的非递增序列(构成一个俄罗斯方块
) 然后我们一定能从右边拿完
但在从左至右的过程中 如果sum>a[1]了 那么题目已然无解 因为我从左至右拿 而我最左边的变为了负数 那么必然无解
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=3e4+10;
int a[N];
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int flag=1,sum=0;
for(int i=1;i<n;i++){
if(a[i]>a[i+1])sum+=a[i]-a[i+1];//加上要减去的值
if(sum>a[1]){//当第一个值无法使得后面成为非递减序列时 No
flag=0;
break;
}
}
if(flag)puts("YES");
else puts("NO");
}
return 0;
}