Codeforces Round #662 (Div. 2)

A. Rainbow Dash, Fluttershy and Chess Coloring

题意:

n ∗ n n*n nn 的方格棋盘,现有黄蓝两种颜色,一圈一圈的图色,使得上一圈与下一圈相邻。试问总共最少要多少回合?

手动写几个找找规律。

AC代码:
int n, m;
 
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sd(n);
		pd(n / 2 + 1);
	}
	return 0;
}

B. Applejack and Storages

题意:

n n n 块木板,再 q q q 次询问的情况下(询问时会添加或者减少木板),问在当前询问下是否能使用现有的木板构成一个正方形和一个矩形(也可以是正方形)?构成的时候,每一条边是只能用一块木板。

统计每个长度出现的次数,判断相同长度的个数是否为 2 2 2 的倍数或者 4 4 4 的倍数

AC代码:
const int N = 1e5 + 50;

int x, cnt[N];
int main()
{
	int n, q;
	sd(n);
	rep(i, 1, n)
	{
		sd(x);
		cnt[x]++;
	}
	int cnt2 = 0, cnt4 = 0;
	rep(i, 1, 100000)
	{
		cnt2 += cnt[i] / 2;
		cnt4 += cnt[i] / 4;
	}
	sd(q);
	while (q--)
	{
		char op[5];
		ss(op + 1);
		sd(x);
		cnt2 -= cnt[x] / 2;
		cnt4 -= cnt[x] / 4;
		if (op[1] == '+')
			cnt[x]++;
		else
			a[x]--;
		cnt2 += a[x] / 2;
		cnt4 += a[x] / 4;
		if (cnt4 > 0 && cnt2 >= 4)
			puts("YES");
		else
			puts("NO");
	}
	return 0;
}

C. Pinkie Pie Eats Patty-cakes

题意:

给你一个数组,问你怎样摆放该数组中的数可以使得数组中相同数之间的距离的最小值最大。

找到出现次数最多的那个数的次数,如果总数是奇数并且出现次数最多的比总数一半还多或者总数是偶数出现次数最多的比一半多那么就是 0 0 0

接下来就是二分,二分每一组的数量,最后答案 − 1 -1 1

AC代码:
const int N = 1e5 + 10;
int n, q;
int a[N], cnt[N];

bool judge(int mid)
{

	int res = n / mid;
	int tmp = res;
	int sum = mid * res;
	if (n % mid)
		tmp++;
	rep(i, 1, n)
	{
		if (cnt[i] > tmp)
			return false;
		sum -= min(res, cnt[i]);
	}
	return sum <= 0;
}

int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sd(n);
		rep(i, 1, n)
			cnt[i] = 0;
		int maxn = 0;
		rep(i, 1, n)
		{
			sd(a[i]);
			cnt[a[i]]++;
			maxn = max(maxn, cnt[a[i]]);
		}
		if ((n & 1) && maxn > (n / 2 + 1))
		{
			puts("0");
			continue;
		}
		if ((n % 2 == 0) && maxn > n / 2)
		{
			puts("0");
			continue;
		}
		int l = 1, r = n;
		int ans = 0;
		while (l <= r)
		{
			int mid = (l + r) >> 1;
			if (judge(mid))
			{
				ans = mid;
				l = mid + 1;
			}
			else
				r = mid - 1;
		}
		ans--;
		pd(ans);
	}
	return 0;
}

D. Rarity and New Dress

题意:

给你一个 n ∗ m n*m nm 的由字母组成的矩阵,,问你这个矩阵中有多少个“相同字母组成的菱形”。

每个菱形显然可以分为上三角和下三角拼成的

那么以这个格子为中心的最大菱形就是 m i n ( 最 大 上 三 角 , 最 大 下 三 角 ) min(最大上三角,最大下三角) min(,) 接下来就是 d p dp dp 最大上三角(下三角了)

我们令 l [ i ] [ j ] l[i][j] l[i][j] 表示 ( i , j ) (i,j) (i,j) 向左延伸的最大同色格子 r [ i ] [ j ] r[i][j] r[i][j] 表示 ( i , j ) (i,j) (i,j) 向右延伸的最大同色格子, m i d [ i ] [ j ] = m i n ( l [ i ] [ j ] , r [ i ] [ j ] ) mid[i][j]=min( l[i][j],r[i][j] ) mid[i][j]=min(l[i][j],r[i][j]) ,表示 ( i , j ) (i,j) (i,j) 为中心的一行最多作为哪个尺寸的三角。

那么最大上三角的转移方程是,当上面的格子和自己同色时 u p [ i ] [ j ] = m i n ( u p [ i − 1 ] [ j ] + 1 , m i d [ i ] [ j ] ) up[i][j]=min(up[i−1][j]+1,mid[i][j]) up[i][j]=min(up[i1][j]+1,mid[i][j])

u p [ i − 1 ] [ j ] up[i−1][j] up[i1][j] 表示接着上面的尺寸,自己这行再加大一个尺寸,但是不能超过 m i d [ i ] [ j ] mid[i][j] mid[i][j]

当上面的格子和自己不同色时, u p [ i ] [ j ] = 1 up[i][j]=1 up[i][j]=1

AC代码:
const int N = 2010;
char s[N][N];
int l[N][N], r[N][N], mid[N][N];
int n, m, up[N][N], down[N][N];
int main()
{
	int n, m;
	sdd(n, m);
	rep(i, 1, n)
	{
		rep(j, 1, m)
		{
			cin >> s[i][j];
		}
	}
	rep(i, 1, n)
	{
		rep(j, 1, m)
		{
			if (s[i][j] == s[i][j - 1])
				l[i][j] = l[i][j - 1] + 1;
			else
				l[i][j] = 1;
		}
		per(j, m, 1)
		{
			if (s[i][j] == s[i][j + 1])
				r[i][j] = r[i][j + 1] + 1;
			else
				r[i][j] = 1;
			mid[i][j] = min(l[i][j], r[i][j]); //横向的长
		}
	}
	rep(i, 1, m)
	{
		rep(j, 1, n)
		{
			if (s[j][i] == s[j - 1][i])
				up[j][i] = min(mid[j][i], up[j - 1][i] + 1);
			else
				up[j][i] = 1;
		}
		per(j, n, 1)
		{
			if (s[j][i] == s[j + 1][i])
				down[j][i] = min(mid[j][i], down[j + 1][i] + 1);
			else
				down[j][i] = 1;
		}
	}
	int ans = 0;
	rep(i, 1, n)
	{
		rep(j, 1, m)
		{
			ans += min(up[i][j], down[i][j]);
		}
	}
	pd(ans);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值