A
Solution
直接枚举即可。时间复杂度 。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int d,l,r;
signed main()
{
cin>>l>>r>>d;
if (l%d!=0) l=l+(d-l%d);
r=(r/d)*d;
cout<<((r-l)/d)+1<<endl;
return 0;
}//数学解法
B
Solution
直接模拟即可。
时间复杂度 。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[20005];
signed main()
{
cin>>n;
for (int i=1;i<=n;i++) cin>>a[i];
int tot=0;
for (int i=1;i<=n;i++)
{
if (i%2==1&&a[i]%2==1) tot++;
}
cout<<tot<<endl;
return 0;
}
C
Solution
直接打表即可。注意尽量控制计算机上打表的时间,并利用这段时间思考别的题目。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int n;
cin>>n;
for (int i=0;i<n;i++) cout<<ans[i]<<endl;
}
D
Solution
比较神仙的一道题目(虽然本蒟蒻做出来了),有思维含量和很多卡点。
首先,考虑一下朴素做法。我们每次枚举到 ,将 翻转然后用高精度暴力求出当前二进制数表示的十进制数,然后求出它的 值即可。
显然此时会TLE。那么我们该怎么办呢?
优化1: 去除重复计算!
先求出读入的二进制数所表示的十进制数 。
枚举到 时,若 为 那么应当把 变为 ,此时 加上了第 位的权值即 ;若 为1,那么同理, 减去了第 位的权值即 。
所以,我们每次不需要暴力地翻转然后求其表示的十进制数,我们只需要按上述方式加或减一个值即可。
优化2: 去除高精计算!
假设我们通过优化 得到了当前翻转之后表示的十进制数为 。无论如何,经过第一步 , 就立即变成了一个可以用 存下的一个数( 小于等于 )。于是,我们考虑直接求出第一步之后的 。
假设读入的
串中有
个1。同样是两种情况:
①若
是
,那么翻转后
的数量为
,此时在第一步之后
。
②若
是
,那么翻转后
的数量为
,此时在第一步之后
。
于是,我们可以对于每个模数 分别求出 的值,然后就可以快速地求出答案并取消高精度计算了。
保守地咕一下时间复杂度:
于是,我们开始不停地获得罚时 分的礼包。显然您肯定是因为 或 而被罚时的。
这里给大家 个 数据的输入数据,基本保证能够找出问题:
3
100
1
0
1
1
6
000000
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int mod1,mod2;
int n,tot=0,pos1=1,pos2=1,tot1=0,tot2=0;
int a[200005];
inline int Popcount(int x)
{
if (x==0) return 0;
int step=0;
while (x!=0)
{
int cnt=0,k=x;
while (k!=0)
{
if (k%2==1) cnt++;
k/=2;
}
if (cnt!=0) x%=cnt;
else x=0;
step++;
}
return step;
}
int quick_power1(int x,int y)
{
int res=1;
for (;y;y=y>>1,x=(x*x)%mod1)
{
if (y&1) res=(res*x)%mod1;
}
return res;
}
int quick_power2(int x,int y)
{
int res=1;
for (;y;y=y>>1,x=(x*x)%mod2)
{
if (y&1) res=(res*x)%mod2;
}
return res;
}
signed main()
{
cin>>n;
for (int i=1;i<=n;i++)
{
char x;
cin>>x;
a[i]=x-'0';
}
for (int i=1;i<=n;i++)
{
if (a[i]==1) tot++;
}
int flag=1;
for (int i=1;i<=n;i++)
{
if (a[i]!=0)
{
flag=0;
break;
}
}
if (flag==1)
{
for (int i=1;i<=n;i++) cout<<1<<endl;
return 0;
}
mod1=tot-1;
mod2=tot+1;
for (int i=n;i>=1;i--)
{
if (mod1!=0) tot1=(tot1+a[i]*pos1)%mod1,pos1=(pos1*2)%mod1;
if (mod2!=0) tot2=(tot2+a[i]*pos2)%mod2,pos2=(pos2*2)%mod2;
}
for (int i=1;i<=n;i++)
{
if (a[i]==0)
{
int now;
if (mod2>0)
{
now=(tot2+quick_power2(2,n-i))%mod2;
cout<<Popcount(now)+1<<endl;
}
else cout<<0<<endl;
}
else
{
int now;
if (mod1>0)
{
now=((tot1-quick_power1(2,n-i))%mod1+mod1)%mod1;
cout<<Popcount(now)+1<<endl;
}
else cout<<0<<endl;
}
}
return 0;
}
E
考试的时候以为E比D难,实则不然。
Solution
我们先把骆驼分成两份,第一份是喜欢在前面的(即 ),第二份是不喜欢在前面的(即 )。
显然第一份与第二份骆驼分别是独立的,即互相不影响。下面介绍一下第一份骆驼的摆放思路,第二份的摆放思路相同。
我们按照 值从小到大进行排序。当看到这个骆驼的时候,我们看一下它是否有位置;如果有的话就直接把它插入队列并计算相应的贡献。如果没有的话,我们贪心地尝试用它换掉占它位置且目前最差(即对答案贡献更少)的骆驼。如果不能换(即该骆驼比之前最差的骆驼还要差)就扔掉这匹骆驼,否则就用它换掉目前最差的骆驼。
于是,我们每次只需要找到最差的骆驼,比较之后决定是否交换即可。
时间复杂度 。
这么做显然会超时。考虑优化。
可以发现,刚才想到的朴素做法中,我们每次都把所有安定下来的骆驼给扫一遍,找出最差的骆驼。
这是不必要的。由于每次最多插入一只骆驼(扫到的那个骆驼进入队列或不进入此队列),那么我们就可以直接使用优先队列来优化。
时间复杂度 )。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int T,n,posa=0,posb=0,k,l,r,ans;
priority_queue<int,vector<int>,greater<int> >q1, q2;
struct node
{
int L,R,K;
}A[200005],B[200005];
bool cmp(node x,node y)
{
return x.K<y.K;
}
inline void clear()
{
posa=posb=0;
ans=0;
}
signed main()
{
cin>>T;
while (T--)
{
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>k>>l>>r;
if (l>r) A[++posa].L=l,A[posa].R=r,A[posa].K=k;
else B[++posb].L=l,B[posb].R=r,B[posb].K=n-k;
ans+=min(l,r);
}
sort(A+1,A+1+posa,cmp);
sort(B+1,B+1+posb,cmp);
for (int i=1;i<=posa;i++)
{
if (A[i].K==0) continue;
else if (q1.size()<A[i].K) q1.push(A[i].L-A[i].R);
else if (q1.size()==A[i].K&&q1.top()<A[i].L-A[i].R)
{
q1.pop();
q1.push(A[i].L-A[i].R);
}
}
for (int i=1;i<=posb;i++)
{
if (B[i].K==0) continue;
if (q2.size()<B[i].K) q2.push(B[i].R-B[i].L);
else if (q2.size()==B[i].K&&q2.top()<B[i].R-B[i].L)
{
q2.pop();
q2.push(B[i].R-B[i].L);
}
}
while (!q1.empty())
{
ans+=q1.top();
q1.pop();
}
while (!q2.empty())
{
ans+=q2.top();
q2.pop();
}
cout<<ans<<endl;
}
return 0;
}
总结&&反思
① 题中,没有考虑边界数据导致出现两次 。应该在做题之后思考边界数据,然后 自己几次,确保 之后再提交。
② 题AC后彻底疯掉,导致无法静下心来思考 题。如果是刷题刷到了 题,那么 还是有指望的;绝对不能满足,不能再出现比赛结束前咕咕咕鸽子飞走的事情(除非 )。
③ 题一直没反应过来打表,浪费了 分钟时间。
太菜了QWQ QAQ 喵~~~