昨天打了一场Div 2,做了三题吧,赛后补了D,前四题都是思维题没什么算法,赛后跟群友讨论了下思路,感觉自己的方法都比较笨吧,再来梳理梳理思路,(其实总感觉自己打cf以及atcoder有的时候是乱搞出来的,自己不能给别人讲的很明白,还是慢慢练吧…毕竟自己思维一直不好)
A题
题解:感觉算是一个性质吧,就是如果我们找到一个n>=2的数,从这个数到2*n-2,这些数全部都是不能互相除尽的。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int t,n,m;
int a,b;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=n*2;i<=4*n-2;i+=2)
{
if(i==2*n) cout<<i;
else cout<<' '<<i;
}
cout<<endl;
}
}
B题
思路:其实就是遍历字符串,如果是第一个1,那么它没有选择只能选择引爆,如果是之后的1,它有两种选择,一种是直接引爆,另一种是把它和前面一个1之间的零全部填上炸弹,然后取这两种的最小费用就可以了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int t,n,m;
int a,b;
int s[N];
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b;
string s;
cin>>s;
int z=-10;
int idx=0;
long long ans=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='1')
{
if(z<0)
{
z=i;
ans+=a;
}
else
{
ans+=min(a,b*(i-z-1));
z=i;
}
}
}
cout<<ans<<endl;
}
}
C题
思路:C题就是我感觉跟大佬有差距的地方了,我用的真的是特别朴素的模拟,然而赛后其他很多人都是用的二分查找以及二分答案做出来的,据说这道题可以不用sort,那样的话算法复杂度会降低很多;其实就是说如果你用到sort,那么这道题复杂度一定是nlongn的,那样子你用模拟和二分对复杂度都是没影响的,但如果不用排序的话复杂度就会低了。我的思路就是用一个结构体存起来两个时间,然后按照快递的时间从大到小排序,因为我们最大时间取决于我们快递时间最长以及自己去取的时间,因而我们只要一直增大自己取的时间,减少最大快递时间,即可得到最短时间
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
ll t,n,m;
ll a[N],b[N];
struct node{
ll x;
ll y;
}nodes[N];
bool cmp(node h,node j)
{
if(h.x==j.x)
return h.y<j.y;
else
{
return h.x>j.x;
}
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
}
for(int i=1;i<=n;i++)
{
nodes[i]={a[i],b[i]};
}
sort(nodes+1,nodes+1+n,cmp);
ll ans=nodes[1].x;
ll res=0;
nodes[n+1].x=0;
for(int i=1;i<=n;i++)
{
res+=nodes[i].y;
if(res<=nodes[i+1].x)
{
ans=nodes[i+1].x;
}
else break;
}
cout<<min(res,ans)<<endl;
}
}
D题
思路:比赛的时候想的是按照对称性,外层两个数的和要大于内层两个数的和,然后wa了,赛后看了别人的想法,明白了这只是充分条件,什么意思?也就是不满足这个条件也有能成立的,然后看了群友的想法:遍历数组,如果当前的数比下一个数大,就没问题,因为此时下一位数只需要从前面减就能减到0,而当当前数小于下一位时,那么下一位数就需要有一部分从后面减才行,此时我们用一个变量加上此时需要从后面减的值,即:a[i+1]-a[i],而后面的每一位都要大于这个变量,因为从后面减时他们也要被减,这样循环下来,如果整个数组都满足就能全都减为0了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=30005;
typedef long long ll;
ll s[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i];
}
ll ans=0;
bool jud=true;
for(int i=1;i<=n-1;i++)
{
if(ans>s[i])
{
jud=false;
break;
}
if(s[i+1]>s[i]) ans+=s[i+1]-s[i];
}
if(s[n]<ans) jud=false;
if(jud) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}