A. New Year Garland
题意:(老套路了)
- 有三个颜色。
- 问是否可以构成首尾相连的。(且不同颜色)
思路:
- 最多颜色为C,其次是b,最少为a。
- 看代码即可。很短了。。
反思:
- 对于一些条件,能短就短。。。。(现在能力还是不行吗。。)
AC(赛后,radewoosh
%%%%%)
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int a[4];
void ans(int x){
if(x)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tt;cin>>tt;
while(tt--){
for(int i=1; i<=3; i++)cin>>a[i];
sort(a+1,a+1+3);
if(a[3]<=a[1]+a[2]+1)ans(1);
else ans(0);
}
return 0;
}
AC(赛时,还写abs,。。。。。)
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int a[4];
void ans(int x){
if(x)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tt;cin>>tt;
while(tt--){
for(int i=1; i<=3; i++)cin>>a[i];
sort(a+1,a+1+3);
if( abs(a[1]+a[2]-a[3]) <= 1)ans(1);//cout<<'no'<<endl;
else if(a[1]+a[2]>a[3])ans(1);
else ans(0);
}
return 0;
}
B. Verse For Santa
题意:
有n个事件,每个事件要消耗时间
a
i
a_i
ai.
每个事件必须按顺序执行。现在可以跳过其中一个事件。
问:
只有可以使完成的事件最大。
输出跳过的事件
思路:
- 可以二分,前缀找。
- 但是本题扫一遍暴力即可。
反思:
- 二分wa在一个特判。
AC(暴力即,贪心地取最大值)
#include <iostream>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pll;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tt;cin>>tt;
while(tt--){
ll n,s;
cin>>n>>s;
pa maxi{0,0},ans{0,0};
ll x,pre=0;
for(int i=1; i<=n; i++){
cin>>x;
maxi=max(maxi,{x,i});
pre+=x;
if(pre<=s)ans=max(ans,{i,0});
if(pre-maxi.first<=s)ans=max(ans,{i-1,maxi.second});
}
cout<<ans.second<<endl;
}
return 0;
}
AC(二分)
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll pre[maxn],a[maxn];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tt;cin>>tt;
while(tt--){
ll n,s;cin>>n>>s;
pre[0]=0;
for(int i=1; i<=n; i++)cin>>a[i],pre[i]=pre[i-1]+a[i];
ll ans=0,mx=0;
ll mid,val;
val=s;
mid=lower_bound(pre+1,pre+1+n,val)-pre;
if(mid==n+1||pre[mid]>val)mid--;
mx=mid;
if(mid==n){
cout<<ans<<endl;
continue;
}
for(int i=1; i<=mid+1&&i<=n; i++){// 有一个情况是 mid+1 的特判
ll val=s;
val+=a[i];
ll pos=lower_bound(pre+1,pre+1+n,val)-pre;//if(pos==i)continue;
if(pos==n+1||pre[pos]>val)pos--;
if(pos-1>mx){
ans=i;
mx=pos-1;
}
}
cout<<ans<<endl;
}
return 0;
}
C. Stack of Presents
题意:
给你一个栈。和一个礼物序列。
礼物要对应(礼物从栈中拿)。
对于礼物
i
i
i 的时间,为
i
i
i 礼物上面有k个礼物。2*k+1.(之后再把k个放回去时,可以任意顺序)
思路:
- 每次取 i i i礼物时,假如当前 i i i在之前的k个中,那么就可以马上抓到。
- 否则就要一直抓到 i i i,对于中途遇到的记录一下。
AC
#include <iostream>
#include <map>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
map<int,int>have;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tt;cin>>tt;
while(tt--){
have.clear();
int n,m;cin>>n>>m;
vector<int>a,b;
int x;
for(int i=1; i<=n; i++)cin>>x,a.push_back(x);
for(int i=1; i<=m; i++)cin>>x,b.push_back(x);
ll ans=0;
stack<int>gift;
for(int i=n-1; i>=0; i--)gift.push(a[i]);
ll has=0;
for(int i=0; i<m; i++){
if(have.count(b[i]))ans++,has--;
else {
while(!gift.empty()&&gift.top()!=b[i])has++,have[gift.top()]++,gift.pop();
ans+=1+2*has;gift.pop();
}
}
cout<<ans<<endl;
}
return 0;
}