比赛连接
https://codeforces.com/contest/1634
A. Reverse and Concatenate(思维)
题意
t组输入,每一组输入两行,第一行输入一个n和k分别表示字符串的长度,k表示可操作的次数,我们每次可以有两种操作:
- 将当前字符串复制后,放在当前字符串后面
- 将当前字符串复制后,放在当前字符串的前面
问最终有几种不同的字符串
思路
我们来思考最终字符串的个数可能的情况,无非就两种:
- 两种字符串都相等:1
- 两种字符串都不相等:2
我们再来想什么时候无论怎么操作字符串都会相等呢,不难看出,当回文字符串的时候,在前面添加或者在后面添加都不会有影响,所以我们只需要判断一下当前的字符串是否是回文字符串即可
代码
#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
ll ksm(ll a,ll b) {
ll ans = 1;
for(;b;b>>=1LL) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
}
return ans;
}
ll lowbit(ll x){return -x & x;}
const int N = 2e6+10;
//----------------自定义部分----------------
int n,m,q,a[N];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int t;
cin>>t;
while(t--) {
cin>>n>>m;
string s;
cin>>s;
int ans = 1;
bool fg = true;
for(int i = 0;i < n/2; ++i) {
if(s[i] != s[n-i-1]) fg = false;
}
if(!fg && m) ans++;
cout<<ans<<endl;
}
return 0;
}
B. Fortune Telling(思维+奇偶性)
题意
一开始alice的数字为x,bob的数字为x+3,然后有一串序列a,我们从前往后遍历这个序列,每次alice和bob必须和这个序列当前位置的数进行一些一下两个操作
- 加上该数
- 异或上该数
问最后所有操作完成后,谁的数字会刚好变成y,题目保证数据有且只有一个人最后到达y
思路
这里我们能知道alice和bob一个为奇一个为偶,每次对奇数进行一个操作都会更改奇偶性,所以我们只需要统计a数组里面奇数的数量,然后判断alice经过这么多次奇偶更改是否和y的奇偶相同,如果是的话输出alice即可
代码
#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
ll ksm(ll a,ll b) {
ll ans = 1;
for(;b;b>>=1LL) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
}
return ans;
}
ll lowbit(ll x){return -x & x;}
const int N = 2e6+10;
//----------------自定义部分----------------
ll n,x,y,m,q,a[N];
void slove(){
ll alice = x & 1,bob = (x + 3) + n;
for(int i = 1;i <= n; ++i) if(a[i] & 1) alice ^= 1;
y &= 1;
if(alice == y) cout<<"Alice"<<endl;
else cout<<"Bob"<<endl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
ll t;
cin>>t;
while(t--) {
cin>>n>>x>>y;
for(ll i = 1;i <= n; ++i) {
cin>>a[i];
}
slove();
}
return 0;
}
C. OKEA(思维+构造)
题意
给你一个 n × k n\times k n×k的矩阵,1到 n × k n\times k n×k的每个数字只能使用一次,然后将这些数字填充到这个矩阵中,要求这个矩阵每一行的每一个区间都能被起区间长度整除,求构造这样的矩阵,如果不能构造则输出NO,否则输出YES,并输出该矩阵
思路
对于k为的情况,我们会发现无论n是多少,都一定能满足
然后我们能先到对每一行构造一个等差数列即可,最简单的等差数列就是按奇偶构造,即:1 3 5 7 9 ……
,2 4 6 8 10 ……
,那么我们来思考什么情况不能构造成功呢,其实就是n为奇数的时候
代码
#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
ll ksm(ll a,ll b) {
ll ans = 1;
for(;b;b>>=1LL) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
}
return ans;
}
ll lowbit(ll x){return -x & x;}
const int N = 5e2+10;
//----------------自定义部分----------------
int n,k,m,q,a[N][N];
void slove(){
if(k == 1){//特判
cout<<"YES"<<endl;
for(int i = 1;i <= n; ++i) cout<<i<<endl;
return;
}
if(n % 2 == 0){
cout<<"YES"<<endl;
int i = 1,loc1 = 1,loc2 = 2;
for(int j = 1;j <= n/2; ++j) {
for(int l = 1;l <= k; ++l) {
a[j][l] = loc1;
loc1+=2;
}
}
for(int j = n/2+1;j <= n; ++j) {
for(int l = 1;l <= k; ++l) {
a[j][l] = loc2;
loc2+=2;
}
}
for(i = 1;i <= n; ++i) {
for(int j = 1;j <= k; ++j) {
cout<<a[i][j]<<" \n"[j == k];
}
}
}
else{
cout<<"NO"<<endl;
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int t;
cin>>t;
while(t--) {
cin>>n>>k;
slove();
}
return 0;
}