A
题意
给定一个
n
n
n,构造一个长度为
n
n
n的数组
a
a
a,满足:1.
a
a
a的任意子数组的和均能被其长度整除;2.
1
≤
a
i
≤
100
1 \le {a_i} \le 100
1≤ai≤100。
思路
方法很多,直接输出长度为
n
n
n的全1数组即可。
代码
#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;
int t,n;
int main() {
cin>>t;
while(t--) {
cin>>n;
for(int i=1;i<=n;i++) cout<<1<<' ';
cout<<endl;
}
return 0;
}
B
题意
给定一个长度为
n
n
n的数组
b
b
b,另有一数组
a
a
a满足
a
i
=
2
b
i
(
1
≤
i
≤
n
)
{a_i} = {2^{{b_i}}}(1 \le i \le n)
ai=2bi(1≤i≤n),判断是否存在不相交的两段子数组
[
l
1
,
r
1
]
\left[ {{l_1},{r_1}} \right]
[l1,r1]、
[
l
2
,
r
2
]
\left[ {{l_2},{r_2}} \right]
[l2,r2],满足
∑
i
=
l
1
r
1
a
i
=
∑
i
=
l
2
r
2
a
i
\sum\limits_{i = {l_1}}^{{r_1}} {{a_i} = } \sum\limits_{i = {l_2}}^{{r_2}} {{a_i}}
i=l1∑r1ai=i=l2∑r2ai。
思路
只有当
b
b
b数组中的元素互不相同的时候就不存在满足要求的两段子数组。
代码
#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;
const int N=1005;
int t,n;
int b[N];
int main() {
cin>>t;
while(t--) {
cin>>n;
unordered_map<int,int> um;
for(int i=1;i<=n;i++) {
cin>>b[i];
um[b[i]]++;
}
int fl=0;
for(int i=1;i<=n;i++) {
if (um[b[i]]>1) {
fl=1;
cout<<"YES"<<endl;
break;
}
}
if (!fl) cout<<"NO"<<endl;
}
return 0;
}
C
题意
给定一个
n
×
m
n \times m
n×m的矩阵
a
a
a,将矩阵中的某些元素加1,构造出一个使所有相邻元素不同的矩阵,可以证明这样的矩阵一定存在。
思路
将这个矩阵的数交错奇偶排列,不满足要求修改当前的值即可。
代码
#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;
const int N=105;
int t,n,m;
int a[N][N];
int main() {
cin>>t;
while(t--) {
cin>>n>>m;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if (i&1) {
if (j&1 && a[i][j]%2==0) a[i][j]++;
if (j%2==0 && a[i][j]&1) a[i][j]++;
cout<<a[i][j]<<' ';
}
else {
if (j&1 && a[i][j]%2!=0) a[i][j]++;
if (j%2==0 && a[i][j]%2==0) a[i][j]++;
cout<<a[i][j]<<' ';
}
}
cout<<endl;
}
}
return 0;
}
D
题意
给定一个包含
n
n
n个正整数的数组
a
a
a,每次操作可以选择其中三个不同的整数
a
i
{a_i}
ai、
a
j
{a_j}
aj、
a
k
{a_k}
ak,将这三个整数的值变为
a
i
⊕
a
j
⊕
a
k
{a_i} \oplus {a_j} \oplus {a_k}
ai⊕aj⊕ak,即三个数的异或,问是否在不超过
n
n
n次的操作下能将数组所有的数变为相等。
思路
假如有5个数,
{
a
1
,
a
2
,
a
3
,
a
4
,
a
5
}
\{ {a_1},{a_2},{a_3},{a_4},{a_5}\}
{a1,a2,a3,a4,a5},考虑将前3个数做一次操作,数组变为
{
b
,
b
,
b
,
a
4
,
a
5
}
\{ b,b,b,{a_4},{a_5}\}
{b,b,b,a4,a5},再对第3、4、5位置的数做一次操作,数组变为
{
b
,
b
,
c
,
c
,
c
}
\{ b,b,c,c,c\}
{b,b,c,c,c},根据异或的性质,
a
⊕
b
⊕
b
=
a
a \oplus b \oplus b = a
a⊕b⊕b=a,再往前推,选择1、2、3位置的数操作,即可将数组变为相等。注意,这种方法的总操作次数为
n
−
2
n-2
n−2,且必须满足
n
n
n为奇数;当
n
n
n为偶数的时候,整体考虑要通过异或使数组所有数相等,那么数组所有数的异或和应该为0,所以
n
n
n为偶数时,若数组所有数异或和不为0,就不能通过这种操作使所有数相等,反之只需对前
n
−
1
n-1
n−1个数进行操作,这样最后前
n
−
1
n-1
n−1个数的值一定会和最后一个数相等。
代码
#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;
int n;
int a[100005];
int main() {
cin>>n;
int ans=0;
for(int i=1;i<=n;i++) {
cin>>a[i];
ans^=a[i];
}
if (n&1 || (n%2==0 && !ans)) {
cout<<"YES"<<endl;
if (n%2==0) n--;
cout<<n-2<<endl;
for(int i=1;i+2<=n;i+=2) {
cout<<i<<' '<<i+1<<' '<<i+2<<endl;
}
for(int i=n-2;i-2>=1;i-=2) {
cout<<i<<' '<<i-1<<' '<<i-2<<endl;
}
}
else {
cout<<"NO"<<endl;
}
return 0;
}