A、B、C三道题题解
一.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题
(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题
(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;
}