目录
问题 A: Deadly Laser
题目描述
机器人放置在网格的左上角,网格由n行和m列组成,位于单元格(1,1)中。
在一个步骤中,它可以移动到与当前单元相邻的单元中:
(x,y)→(x,y+1);
(x,y)→(x+1,y);
(x,y)→(x,y−1);
(x,y)→(x−1、y)。
机器人不能在网格外移动。
格子(sx,sy)含有致命的激光。如果机器人进入距离激光小于或等于d的格子,它就会蒸发。两个单元(x1,y1)和(x2,y2)之间的距离定义为|x1−x2|+|y1−y2|。
打印机器人在不蒸发并且移动到网格外的情况下到达单元(n,m)所需的最小步数。如果无法到达单元格(n,m),请打印-1。
激光器既不在起始单元中,也不在结束单元中。起始单元与激光器的距离始终大于d。
这道题分两种情况
1.如果能走到,以(1,1)为起点走到(n,m),只要不走回头路,路径最短就是(n-1)+(m-1)即n+m-2。想象一个矩形,原点在左上角,终点在右下角,其中由于(sd,sy)影响部分位置不能通过。因此只要保证能沿着边缘从上边和右边走或者从左边和下边走即可。
2.不能走的话输出-1
问题 B: Corners
题目描述
给出了一个由n行和m列组成的矩阵。该矩阵的每个单元格包含0或1。
在一个操作中,您可以取一个L形图形(形如L的3格)其中至少一个单元格包含1,并将其中的所有数字替换为零。
您可以操作直至数组全变成0
找出给定矩阵可以执行的最大操作数。
直接暴力枚举过每个‘1’的“L”,统计出一个L里面最少容纳有几个’1‘,将这个L转化为’0’,剩下过‘1’的L就都能满足一个L里只有一个‘1’,答案就是‘1‘的个数减去L中最少容纳‘1’的数量加上一
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n,m,sum=0,num,min=3;
scanf("%d%d",&n,&m);
char a[n+2][m+2];
for(int i=0; i<n; i++){
scanf("%s",&a[i]);
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
num=0;
if(a[i][j]=='1'){
num++;sum++;
}
if(i-1>=0){
if(a[i-1][j]=='1')num++;
if(j-1>=0 && a[i][j-1]=='1'){
num++;
if(num<min) min=num;
num--;
}
else if(j-1>=0){
if(num<min) min=num;
}
if(j+1<m && a[i][j+1]=='1'){
num++;
if(num<min) min=num;
num--;
}
else if(j+1<m){
if(num<min) min=num;
}
if(a[i-1][j]=='1')num--;
}
if(i+1<n){
if(a[i+1][j]=='1') num++;
if(j-1>=0 && a[i][j-1]=='1'){
num++;
if(num<min) min=num;
num--;
}
else if(j-1>=0){
if(num<min) min=num;
}
if(j+1<m && a[i][j+1]=='1'){
num++;
if(num<min) min=num;
num--;
}
else if(j+1<m){
if(num<min) min=num;
}
if(a[i+1][j]=='1') num--;
}
num=0;
}
}
if(min!=0) printf("%d\n",sum-min+1);
else printf("%d\n",sum);
}
return 0;
}
问题 C: prime check
题目描述
如果一个正整数大于1且不能写成两个较小的正整数的乘积,则称之为质数
素性测试是一种用于确定输入数是否为素数的算法。例如,Miller-Rabin素性测试是一种概率素性测试。这个问题正是关于素性检验的问题。
让我们将函数f(x)定义为严格大于x的最小素数。例如,f(1) = 2,f(2) = 3,f(3) = f(4) = 5。我们使用⌊�⌋
表示不超过x的最大整数 .
现在给你x,判断g(x)是否为质数.
f(x)和f(f(x))为两个相邻的质数,两个相邻的质数之间的数都是合数,1/2(f(x)+f(f(x))为两质数的平均值,因此为偶数。因为2是唯一的偶质数,四舍五入导致1/2(f(x)+f(f(x))结果为2,而其他质数都是奇数和为偶数,就不会出现上面的特殊情况所以结果都是合数。
问题 D: PolarBear的填色游戏
题目描述
PolarBear十分喜欢玩游戏,最近他发现了一个有趣的填色游戏。游戏中有�个单元格,从左到右一次排成一行。最初,所有的单元格都是白色的。如果一个白色的格子的相邻位置没有任何的红色格子,那么则认为这个格子是有效的。每一回合,玩家可以将任意有效的格子涂成红色,当游戏进行到没有有效格子时,游戏结束。玩家的分数等于他们各自涂红的单元格的数量。
PolarBear玩到入迷了,开始四处虐菜,今天他遇到了自己的手下败将dongdziz。dongdziz并不会玩这个游戏,但他坚信如果一直涂最左边的有效格子那么一定可以胜利,因此每每轮到他时,他只会将最左边的有效格子涂成红色。但PolarBear并不想赢,他只想最小化dongdziz的分数。可惜PolarBear也不想思考,他想问问你,如果PolarBear以最佳的方式最小化dongdziz的得分,dongdziz最多可以获得多少分。(dongdziz先进行第一步,然后双方轮流涂直到没有有效格子)
用D代表dongdziz填色,0代表空格,P代表PolarBear填色,则D00P0D00P0…….是最小化分数的填色方式,所以只需要看格数与5的关系即可
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
int t,n,s,k;
cin>>n;
cout<<(n-1)/5+1<<endl;
return 0;
}
问题 E: 呆唯和连通分量
这道题其实也只需分两种情况
- 如果以及连通且最大的连通环量<=n满足要求不需要移动。
- 2.如果不满足要求,只需要移动一位把最大的连通环拆成两个就行,因为一个大于n其他环必然小于n,均满足要求。
我是模拟了链表的方式,来记录环连通的量,再用st[]保存状态优化了一下
问题 F: 小z的序列
1、2、3、4、5如果都是不同的数除了1其他的数都能找到比它小的数
如果有重复1、1、3、4、5,取出其中的1、3、4、5除了1其他数都能找到比他小的数,剩下重复的1多余
因此假设其中出现次数最多为n,第二多为a。必然可以找到a组数,满足互异性,而n-a个数多余,因此有n-a+a个数不能找到比他小的数。综上输出总数减众数个数即可。
问题 G: AB Palindrome
题目描述
给出一个由A和B构成的字符串,可以用AB替换其中的连续两个字符,并且可以替换多次,问是否能最终成为回文
字符串长度小于200000
尝试一下即可发现,因为可以用AB替换,所以除了A????B这种形式的字符串,其他字符串都可以变成回文字符串
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
int t, n ;
string a;
cin >> t;
for (int i = 0; i < t; i++) {
cin >> n;
cin>>a;
if(a[0]=='A'&&a[n-1]=='B')
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
return 0;
}
问题 H: Interesting Sum
题目描述
给您一个包含n个整数的数组a。他是一个环,你可以任意选两个不重合的子段,使得两个子段的 最大值减去最小值的和最大
请输出可以得出最大的数
最大的和一定等于最大的两个数减去最小的两个数,因为是一个环,所以这四个值一定能被同时取到
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int a[n];
for(int i=0; i<n; i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
printf("%d\n",a[n-1]+a[n-2]-a[0]-a[1]);
}
return 0;
}
问题 I: 计算圆周率
直接输出8即可
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "8" << endl;
return 0;
}
问题 J: AB Game
题目描述
这个游戏是由爱丽丝和鲍勃玩的。最初,有n个石头。
玩家交替轮换,做出如下所述的动作,艾丽斯先走。无法移动的玩家将失败。
轮到艾丽斯时,她必须取出a的正倍数的石头。
轮到鲍勃时,他必须取出B的正倍数的石头。
那么在总共有1个石头,2个石头,3个石头.....n个石头的n长游戏中,当两个玩家都以最佳方式玩时,Alice赢了多少次?
分情况讨论结果
1. n < a
2. n ≥ a
(1) a ≤ b
(2) a > b ((1))(n % a) >= b
((2))(n % a) < b
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
long long int t, n, a, b;
cin >> t;
for (long long int i = 0; i < t; i++) {
cin >> n >> a >> b;
if (n < a) {
cout << 0 << endl;
} else if (n >= a && a <= b) {
cout << n - a + 1 << endl;
} else if (n >= a && a > b && (n % a) >= b) {
cout << n / a*b << endl;
} else if (n >= a && a > b && (n % a) < b) {
cout << (n / a - 1)*b + n % a + 1 << endl;
}
}
return 0;
}