https://codeforces.com/contest/1369
A
猜结论,一开始盲猜 (n mod 2=0),然后 WA 了,画了一画,改成 (n mod 4=0),然后 A 了。
时间复杂度 (O(t))。
#include<bits/stdc++.h>
using namespace std;
int t,n,an;
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
if(n%4)
puts("NO");
else
puts("YES");
}
}
B
对于这一类序列而言 (1ldots10ldots0),其可以被变成 (0)。
将两个序列连起来,也可以变成 (0)。
所以统计一下前缀 (0) 和后缀 (1),这是要保留的。
中间如果有值,就输出 (0)。
时间复杂度 (O(tn))。
#include<bits/stdc++.h>
using namespace std;
int t,n,opt,l,r;
char st[100010];
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d
",&n);
for(int i=1;i<=n;i++)
st[i]=getchar();
l=1,r=n;
while(st[l]=='0')
l++;
while(st[r]=='1')
r--;
if(l>r)
for(int i=1;i<=n;i++)
printf("%c",st[i]);
else {
for(int i=1;i<l;i++)
printf("0");
printf("0");
for(int i=r+1;i<=n;i++)
printf("1");
}
puts("");
}
}
C
考虑贪心。
将 (a) 从大到小排序,(w) 从小到大排序。
先满足需求为 (1) 的,随后从大到小满足。
因为我们可以让最大的带走一堆最小的!
时间复杂度 (O(t imes nlog n))
#include<bits/stdc++.h>
using namespace std;
long long t,n,a[200010],w[200010],l,r,zz,k;
long long ans;
int main() {
scanf("%lld",&t);
while(t--) {
scanf("%lld %lld
",&n,&k);
for(long long i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(long long i=1;i<=k;i++)
scanf("%lld",&w[i]);
sort(a+1,a+n+1);
sort(w+1,w+k+1);
ans=0,zz=1;
while(w[zz]==1) {
ans+=a[n]*2;
zz++,n--;
}
l=1,r=n;
while(k>=zz) {
ans=ans+a[l]+a[r];
l=l+(w[k]-1);
r--;k--;
}
printf("%lld
",ans);
}
}
D
找规律。
(dp_n=2 imes dp_{n-2}+dp_{n-1}+(nmod 4=0?4:0))。
时间复杂度 (O(2 imes 10^6+T))。
#include<bits/stdc++.h>
using namespace std;
const int twx=1e9+7;
int n,dp[2000010],t;
int main() {
for(int i=3;i<=2000000;i++)
dp[i]=(dp[i-2]*2%twx+dp[i-1]+(i%3==0?4:0))%twx;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
printf("%d
",dp[n]);
}
}