codeforces div2-- #662

A、B、C三道题题解

一.A题

A题题目链接

(1)题意:

t组测试数据,每组数据有n*n个格子的棋盘,最初都是没颜色的,按照国际象棋的摆法填满整个格子,每次可以选择一种颜色,并且上下左右四个面,至少有一个面旁边有颜色(初始化时候,可以挨着棋盘的边界布置颜色)

(2)题解:

多画几个格子的图后就会发现,除了1*1的棋盘是1步,2 * 2的棋盘是两步之外,其他的棋盘都可以由这两个得到。
例如:3 * 3的棋盘在边界填了一次之后,我们忽略掉最外围的格子(因为肯定一次就可以填满,所以我们主要看里面的格子是什么状态),里面实际上就是1 * 1的棋盘,所以需要两次。
同理4 * 4的格子也是填了一次之后内部实际上是 2 * 2的格子,5 * 5……等也是如此。

(3)代码:

#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue> 
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<functional>

using namespace std;

typedef long long ll;
const int maxn = 1e4 + 10;
const int INF = 0x3f3f3f3f;

int t,n;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		printf("%d\n",n/2+1);
	}
	return 0;
}

二.B题

B题题目链接

(1)题意:

开始公司仓库有n块木板,q次增删,每次 + x 或者 - x,问在增加或者减少之后能不能凑出一个正方形,一个矩形(正方形也是矩形)

(2)题解:

n有1e5,q也有1e5,每次增删之后for循环遍历查找值肯定就是行不通的。
正方形是四个长度相等的边,矩形是两对长度相等的边或者也是四个长度相等的边,所以我们用两个变量cnt1来记录四个相等的边有多少,cnt2来记录两个相等的边有多少,每次增删维护好n、cnt1、cnt2这三个值,当n >= 8 且cnt1 >= 1 且 cnt2 >= 4时就满足条件。

(3)代码:

#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue> 
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<functional>

using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;

int n,q,len,a[maxn],cnt1,cnt2;
int main()
{
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
	{
		int x;
		scanf("%d",&x);
		a[x]++;
		len = max(len,x);
	}
	
	for(int i = 1; i <= len; i++)
	{
		cnt1 += a[i] / 4;
		cnt2 += a[i] / 2;
	}
	scanf("%d",&q);
	
	for(int i = 1; i <= q; i++)
	{
		char ch;
		int x;
		scanf(" %c %d",&ch,&x);
		if(ch == '+')
		{
			a[x]++;
			if(a[x] % 4 == 0)
				cnt1++;
			if(a[x] % 2 == 0)
				cnt2++;
			n++;
		}
		else if(ch == '-')
		{
			if(a[x] % 4 == 0)
				cnt1--;
			if(a[x] % 2 == 0)
				cnt2--;
			a[x]--;
			n--;
		}
		if(n >= 8 && cnt1 >= 1 && cnt2 >= 4)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

三.C题

C题题目链接

(1)题意:

t组测试数据,每组数据有n个数,每组数据中可能有几个相同的数,求两个相同数之间的最大化最小距离

(2)题解:

首先,所求答案应该是由最多相同的那个数决定,所以最先安排相同数量最多的那个数,然后将与他不同的数填充到数与数的间距里面,有多个最大相同的数也要记录下来。

(3)代码:

#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue> 
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<functional>

using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;

int t,n,a[maxn],maxx,cnt,ans;

int main()
{
	scanf("%d",&t);
	while(t--)
	{
		maxx = 0,cnt = 0;
		scanf("%d",&n);
		memset(a,0,sizeof(a));
		for(int i = 1; i <= n; i++)
		{
			int x;
			scanf("%d",&x);
			a[x]++;
		}
		
		for(int i = 1; i <= n; i++)
			maxx = max(maxx,a[i]);
			
		for(int i = 1; i <= n; i++)
			if(a[i] == maxx)
				cnt++;
				
		ans = (n - maxx - cnt + 1) / (maxx - 1);
		printf("%d\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值