首页 > 其他分享 >牛客多校第二场补题

牛客多校第二场补题

时间:2023-07-23 13:23:15浏览次数:36  
标签:int -- 中心对称 多校 牛客 maxn mp solve 补题

牛客多校2

题意:

两个人下五子棋,给出棋盘大小,构造一种方案,使得平局。

思路:

考虑这样构造

xxxxo

oxxxx

xxxxo

oooox

以五一个为一个循环,多出来的部分也以这种方式构造,唯一的问题就是当有奇数行时会导致先手的棋子太多,因此当n为奇数时,让最后一行这样填充

xoxoxox......

#include<bits/stdc++.h>
using namespace std;

int n, m;
const int maxn = 1e3 + 10;
char ans[maxn][maxn];


void print(){
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			cout<<ans[i][j];
		}
		cout<<"\n";
	}
}

void solve(){
	cin>>n>>m;
	if(n < 5){
		for(int i = 1; i <= m; i++){
			for(int j = 1; j <= n; j++){
				if(i % 2 == 1){
					ans[j][i] = 'x';
				}
				else{
					ans[j][i] = 'o';
				}
			}
		}

		if(m % 2 == 1){
			for(int i = (n + 1) / 2 + 1; i <= n; i++){
				ans[i][m] = 'o';
			}
		}
	}
	else if(m < 5){
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				if(i % 2 == 1){
					ans[i][j] = 'x';
				}
				else ans[i][j] = 'o';
			}
		}

		if(n % 2 == 1){
			for(int i = (m + 1) / 2 + 1; i <= m; i++){
				ans[n][i] = 'o';
			}
		}
	}
	else{
		int t1 = m / 5;
		for(int k = 1; k <= t1; k++){
			for(int i = 1; i <= n; i++){
				for(int j = (k - 1) * 5 + 1; j <= k * 5 - 1; j++){
					if(i % 2 == 1){
						ans[i][j] = 'x';
					}
					else ans[i][j] = 'o';
				}
				if(i % 2 == 1) ans[i][k * 5] = 'o';
				else ans[i][k * 5] = 'x';
			}
		}

		int t2 = m % 5;
		for(int i = 1; i <= n; i++){
			for(int j = t1 * 5 + 1; j <= m; j++){
				if(i % 2 == 1) ans[i][j] = 'x';
				else ans[i][j] = 'o';
			}
		}


		if(n % 2 == 1){
			for(int i = 1; i <= m; i ++){
				if(i % 2 == 1) ans[n][i] = 'x';
				else ans[n][i] = 'o';
			}
		}
	}

	print();
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int T = 1;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

E.Square

题意:

给出x,找到y满足\(y^2/10^k =x\)成立,找不到则输出-1,考虑二分答案。

D. The Game of Eating

题意:

有n个人、m道菜,每个人对每道菜都有一个评价,要选k次菜,让每个人的对菜喜爱值的和尽量大。

思路:

首先考虑正着贪心,因为我后面的人可能选到我最喜欢的菜,而我把这道菜选了后面的人的选择就可能不是最优,因此可以发现,当最后一个人选的时候,它不需要考虑后面是否会有人选到我最喜欢的菜,以此类推,倒着贪心一定是最优的。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int maxn = 2e3 + 10;
int n, m, k;
ll a[maxn][maxn];

void solve(){
	cin>>n>>m>>k;
	vector<int>vis(m + 5, 0);
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			cin>>a[i][j];
		}
	}

	vector<int>ans;
	for(int i = k; i >= 1; i--){
		int s = i % n;
		if(s == 0) s = n;
		vector<pair<int, int>>tmp(m + 1);
		for(int j = 1; j <= m; j++){
			tmp[j].first = a[s][j];
			tmp[j].second = j;
		}
		sort(tmp.begin() + 1, tmp.begin() + 1 + m);
 		for(int j = m; j >= 1; j--){
			if(!vis[tmp[j].second]){
				vis[tmp[j].second] = 1;
				ans.push_back(tmp[j].second);
				break;
			}
		}
	}
	sort(ans.begin(), ans.end());
	for(int i = 0; i < k; i++){
		cout<<ans[i]<<" \n"[i == k -1];
	}
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int T = 1;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

题意:

博弈论、两个人对三元组进行操作,当谁操作到之前被操作到的一个位置时,谁就输了

思路:

二分图博弈,当n为偶数时先手一定可以完全匹配,当n为奇数时只有初始位置的和为奇数时后手才能赢。

#include<bits/stdc++.h>
using namespace std;

int n, x, y, z;

void solve(){
	cin>>n>>x>>y>>z;
	int sum = (x + y + z);
	if(sum % 2 == 1){
        if(n % 2 == 1)
		  cout<<"Bob\n";
        else cout<<"Alice\n";
	}
	else cout<<"Alice\n";
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int T = 1;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

题意:

给出一个字符串,判断其能否分成若干个中心对称字符串。

一个字符串被称为中心对成字符串的条件是

image-20230722165816376

思路:

首先中心对称这个概念和回文这个概念是很像的,那么能否用类似Manacher算法的思想做呢。

首先,题目本身的要求是分成若干个中心对成串,那么贪心的去想,假设一个字符串的左端点为l,右端点为r。那么如果[l,r]恰好是一个中心对称串,那么我就在r的位置断开,这样子得到的字符串一定是符合条件的并且按照这样分的策略,也一定能够判断初始的串是否满足条件。可以发现这个过程确实是和manacher类似的。

考虑p[i] 为以i为中心的最长中心对称半径。假设我当前的位置小于我前一个最长中心对称半径的右端点,令其为R,再令左端点为L。那么我就要再判断我的镜像位置的左端点是否小于L。以此来求得我这个位置的最长中心对称半径。如果大于R,那么就需要暴力更新,但是因为更新的过程中i是随着中心一起增加的(参考manacher),因此复杂度是线性的。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 10;
int n;
char s[maxn + 5];
char t[2 * maxn + 5];
char mp[256];

void init(){
	mp['b'] = 'q';
	mp['d'] = 'p';
	mp['p'] = 'd';
	mp['q'] = 'b';
	mp['n'] = 'u';
	mp['u'] = 'n';
	mp['o'] = 'o';
	mp['s'] = 's';
	mp['x'] = 'x';
	mp['z'] = 'z';
	mp['#'] = '#';
}

void solve(){
	cin>>(s + 1);
	n = strlen(s + 1);

	int m = 0;
	t[0] = '$';
	t[++m] = '#';
	for(int i = 1; i <= n; i++){
		t[++m] = s[i], t[++m] = '#';
	}
	t[m + 1] = '\0';
	vector<int>p(m + 1);
	int M = 0, R = 0;
	int start = 1;
	for(int i = 1; i <= m; i++){
		if(i > R) p[i] = -1;
		else p[i] = min(p[2 * M - i], R - i + 1);
		while(t[i - p[i] - 1] == mp[t[i + p[i] + 1]]){
			++p[i];
		}
		if(i + p[i] > R){
			M = i;
			R = i + p[i];
		}
		if(p[i] > 0 && i - p[i] <= start){
			t[i + p[i] - 1] = '$';
			start = i + p[i];
			i = i + p[i] - 1;
		}
	}

	if(start == m) cout<<"Yes\n";
	else cout<<"No\n";
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int T = 1;
	init();
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

标签:int,--,中心对称,多校,牛客,maxn,mp,solve,补题
From: https://www.cnblogs.com/pang-bai/p/17574905.html

相关文章

  • 牛客第一场补题
    牛客多校1D.Chocolate题意:A、B轮流吃巧克力,当一个人选择一个点吃的时候,会把这个点及其左下的所有全部吃完,谁先吃完谁就输了,给出巧克力的大小,问谁会赢。思路:考虑当一个人吃完只剩一行或一列时,那么下一个吃的人就可以控制把最后一块留给这个人,因此当一个人吃完剩一行和一列的......
  • 杭电多校第一场补题
    杭电多校第一场1001Hide-And-SeekGame题意:给出一棵树,每次询问第一个人从Sa-Sb之间来回走,第二个人在Ta-Tb之间来回走,最早相遇的节点,如果无法相遇就输出-1做法:由于数据量是1e3级别,因此对于每一条路径都可以使用暴力找祖先的方法求出路径,然后对于路径上的每一个节点,其出现的时间......
  • 2023牛客暑期多校训练营2 补题
    D.TheGameofEating题意:有n个人和m道菜,每个人对每个菜的都有一个喜好度a[i][j],所有人都知道其他人的喜好度,现在需要上k道菜,从1,2...,n,1,2.....的顺序来选,如果每个人都只考虑自己的喜好,问最后哪些菜会被端上来Solution我们考虑到所有人都知道其他人的喜好度,也就是说,假设当前要选......
  • 牛客多校2
    D.TheGameofEating题意:有\(n\)个人,\(m\)种菜,从\(1\)开始轮流点菜,一共点\(k\)道,\(n\)点完轮到\(1\),直到点完,点过的菜其他人不能再点。第\(i\)个人对第\(j\)道菜有\(A_{i,j}\)的喜好度,每个人都想让自己对所有已选的菜的喜好度总和最大,他们能彼此看到对菜的喜好度,问最后点了的......
  • 暑假牛客多校第二场 2023-7-21
    未补完E.Square算法:二分做法:我们依据x来枚举k,得到\(x*10^k\),用二分在[0,1e9]查找mid的平方值,且这个值是第一个大于等于\(x*10^k\)的值。得到这个值后我们再判断这个值在除\(10^k\)后是否与\(x\)相等即可。code#include<iostream>#include<cstring>#incl......
  • 2023牛客多校7.21补题
    D-TheGameofEating题意:一共有m道菜,n个人轮流点一道菜,一共点k道。第i个人对第j道菜的喜爱程度\(A_{i,j}\)对所有人公开,一个人点了菜所有人都可以吃到。每个人都希望最大化自己的喜爱程度之和,求最终的点菜集合。分析:很容易想到每个人点菜时都点当前剩下的菜中自己最喜爱的,但是......
  • Codeforces Round 886 (Div. 4)补题
    CodeforcesRound886(Div.4)A~D://A:boolsolve(){ cin>>a[1]>>a[2]>>a[3]; sort(a+1,a+4); returna[2]+a[3]>=10?1:0;}//B:voidsolve(){ intn; cin>>n; intmaxa=0; intnum=0; intx,y; for(inti=1;i<=n;i++){cin>......
  • 牛客暑假多校 2023 第二场
    写在前面比赛地址:https://ac.nowcoder.com/acm/contest/57356。我是MINUS-FIFTEEN级超级战犯。澄清一下,我不是声优厨,我不是声优厨,我不是声优厨。同样是题目选补,我是飞舞。以下个人向难度排序。I签到。随便手玩一下就行。D虽然每个人都倾向于吃到自己最喜欢的菜,但给在......
  • 2023 牛客暑期多校
    7.17我正开,Dgjk倒开,AHJKLMA-AlmostCorrect设\(s\)中\(0\)的下标集合为\(S_{0}\),\(1\)的为\(S_{1}\),最右边的\(0\)的下标\(r\),最左边\(1\)的下标\(l\)。\(s\)没有排好序所以\(l\le|S_{1}|<r\)\(\foralli\inS_{0},(i,r)\)\(\foralli\inS_{1},(l......
  • 2023牛客多校2
    H.0and1inBIT题意给一串操作字符串,其中包含操作\(A,B\):\(A\)代表将二进制每一位反转。\(B\)代表将二进制加\(1\)。且当二进制为全\(1\)时,二进制变为全\(0\)现在包含多次询问,每次询问给定一个区间(区间需要计算得到),给定一个初始二进制\(x\),问你二进制在经过操作字符串对......