A - Arithmetic Array
签到
#include <bits/stdc++.h>
using namespace std;
int len,n,t,sum;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&len);
sum = 0;
for(int i=0,tmp;i<len;i++){
scanf("%d",&tmp);
sum += tmp;
}
if(sum == len) printf("0\n");
else if(sum > len) printf("%d\n",sum-len);
else printf("1\n");
}
return 0;
}
B - Bad Boy
我们可以证明:从起点出发到两点a1,a2(没有重复路程)的最小距离就是,分别从起点走到a1再走回去、加上从起点走到a2再走回去的距离,所以我们只要找到两个距离最大的点就行了。
所以我们只要找对角线就可以了。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n,m,i,j;
scanf("%lld%lld%lld%lld",&n,&m,&i,&j);
ll x,y;
x = i>n/2?1:n;
y = j>m/2?1:m;
i = x==n ? 1:n;
j = y==m ? 1:m;
printf("%lld %lld %lld %lld\n",x,y,i,j);
}
return 0;
}
C - Challenging Cliffs
只要找两条单调上升子序列就行了,要终点的绝对值最小
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+500;
ll n;
ll h[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%lld",&n);
for(int i=0;i<n;i++){
scanf("%lld",&h[i]);
}
sort(h,h+n);
if(n==1||n==2){
for(int i=0;i<n;i++) printf("%lld ",h[i]);
printf("\n");
continue;
}
int mark,d = INT_MAX;
for(int i=0;i<n-1;i++){
if(h[i+1]-h[i]<d) {
mark = i;
d = h[i+1]-h[i];
if(!d) break;
}
}
printf("%lld ",h[mark+1]);
for(int i = mark+2;i<n;i++) printf("%lld ",h[i]);
for(int i=0;i<=mark;i++) printf("%lld ",h[i]);
printf("\n");
}
return 0;
}
D - Deleting Divisors
SG函数打表找规律
规律:
- 奇数不行
- 偶数中,2的奇数次幂不行
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int tmp = n,cnt=0;
while(tmp%2==0) tmp/=2, cnt++;
if(n<4) printf("Bob\n"); //特判2
else if(tmp==1&&cnt&1) printf("Bob\n"); //判2的奇数幂
else if(cnt) printf("Alice\n"); //其他偶数
else printf("Bob\n"); //奇数
}
return 0;
}
E1 - Erase and Extend (Easy Version)
python暴力枚举
n,k = map(int,input().split())
str = input()
ans = None
for i in range(1,len(str)+1):
cnt = int(k/i)
if cnt*i != k :
cnt += 1
tmp = str[0:i]*cnt
if i == 1:
ans = tmp[:k]
elif tmp < ans:
ans = tmp[:k]
print(ans)
E2 - Erase and Extend (Hard Version)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5+500;
int n,k;
char str[maxn];
int main(){
scanf("%d%d",&n,&k);
scanf("%s",str);
int ans = 1;
for(int i=1;i<n;i++)
{
if(str[i]>str[i%ans])
break;
if(str[i]<str[i%ans])
ans = i+1;
}
for(int i=0;i<k;i++) printf("%c",str[i%ans]);
printf("\n");
return 0;
}
F - Figure Fixing
二分图的话,要求两边的
∑
v
[
i
]
−
t
[
i
]
\sum{v[i]-t[i]}
∑v[i]−t[i]相等
否则 要求
∑
v
[
i
]
−
t
[
i
]
\sum{v[i]-t[i]}
∑v[i]−t[i]为偶数
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5+500;
vector<int> G[maxn];
ll v[maxn],t[maxn],col[maxn],n,m,sum[2],x;
bool dfs(int now){
for(auto i:G[now]){
if(~col[i]){
if(col[i]==col[now]) return false;
}else{
col[i] = !col[now];
if(!dfs(i)) return false;
}
}
return true;
}
bool solve(){
sum[0] = sum[1] = x = 0;
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&v[i]);
for(int i=1;i<=n;i++) scanf("%lld",&t[i]),col[i]=-1,G[i].clear();
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
col[1] = 0;
bool flag = dfs(1);
for(int i=1;i<=n;i++) sum[col[i]]+=v[i]-t[i],x += v[i]-t[i];
if(flag&&sum[0]==sum[1]) return true;
if(!flag&&x%2==0) return true;
return false;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
solve()?puts("YES"):puts("NO");
}
return 0;
}