A
思路:首先判断字符串s是不是回文。如果s是回文,无论把rev加到s前面还是后面,结果都是一样的,所以答案都是1;如果s不是回文,进行一次操作后会产生2个回文的新字符串,然后无论再进行几次操作答案都是2。
如果这个串是回文串,无论怎么变化都是一种,如果这个串不是回文串,经历过一次变化也会变成回文串
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e6 + 10;
const int ma=1e9+10;
string s;
int n,k;
void solve()
{
scanf("%d %d",&n,&k);
cin>>s;
string tem=s;
reverse(tem.begin(),tem.end());
if(tem==s)
{
cout<<1<<'\n';
}
else
{
if(k==0) cout<<1<<'\n';
else cout<<2<<'\n';
}
}
int main()
{
int _t=1;
scanf("%d", &_t);
while (_t--)
{
solve();
}
//system("pause");
}
B
题意:给定数组长度n,初始值x和x+3,目标值y,对两个初始值分别对数组a中的数按1~n的顺序进行+或xor操作,看哪个初始值可以达到目标值。
思路:注意题目保证一定有解,首先注意到x与x+3奇偶性不同,然后无论进行xor或+操作结果值的奇偶性都是一致的。所以只需把x与所以的数加起来判断是否与y的奇偶性一致即可。
设a为奇数,b为偶数,x为奇数
x + a 为偶数
x xor a 为偶数
x + b 为奇数
x xor b 为奇数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e5 + 10;
const int ma=1e9+10;
ll a[maxx];
ll n,x,y;
void solve()
{
scanf("%lld %lld %lld",&n,&x,&y);
ll tem=x;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
tem+=a[i];
}
if(tem%2==y%2) printf("Alice\n");
else printf("Bob\n");
}
int main()
{
int _t=1;
scanf("%d", &_t);
while (_t--)
{
solve();
}
system("pause");
}
C
题意:给定n和k,将1~n*k个数放到n行k列的矩阵中,并使得每行任意连续个数字的平均值为整数
思路:每行构造公差为2的等差数列
所以每行要么全为奇数,要么全为偶数。
当n*k为偶数时,偶数个数等于奇数个数,所以偶数的行数等于奇数的行数。
当n*k为奇数时,奇数个数等于偶数个数+1,此时只有k=1时才能构造出来。
综上:n为偶数或k=1时可以,否则不可以
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e5 + 10;
const int ma = 1e9 + 10;
int n, k;
void solve()
{
scanf("%d %d", &n, &k);
if (k == 1)
{
printf("YES\n");
for (int i = 1; i <= n * k; i++)
printf("%d\n", i);
}
else if (n % 2 == 0)
{
printf("YES\n");
int cnt = 0;
for (int i = 1; i <= n * k; i += 2)
{
cnt++;
cout << i << " \n"[cnt % k == 0];
}
cnt = 0;
for (int i = 2; i <= n * k; i += 2)
{
cnt++;
cout << i << " \n"[cnt % k == 0];
}
}
else
printf("NO\n");
}
int main()
{
int _t = 1;
scanf("%d", &_t);
while (_t--)
{
solve();
}
system("pause");
}