Codeforces Round #770 (Div. 2)

比赛连接

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;
}
上一篇:Ybtoj #735. 「动态树」毒瘤染色


下一篇:YbtOJ-毒瘤染色【LCT】