作者@TechGuide【全网同名】
第一题:切披萨
题目描述
游游拿到了一个边长为n的正方形披萨,她准备切k刀(每刀只能横着或竖着切开),最终会形成若干个小矩形披萨。
游游希望每个小披萨的面积相等,且矩形的长和宽的差的绝对值尽可能小。你能帮游游求出每个小矩形的面积吗?
输入描述
两个正整数n和k,用空格隔开。1<n,k<100
2 1
输出描述
一个浮点数,代表每个小矩形的面积,小数点后保留2位。
2.00
思路
要求切出来的矩形面积都相等,均匀切即可。
代码
Java版本
import java.util.Scanner;
public class first {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(),k = sc.nextInt();
double v = n+0D;
if(k==1){
System.out.printf("%.2f%n",v*v/2);
return;
}
int x = k>>1;
int y = k-x;
double res = (v*v)/((x+1)*(y+1));
System.out.printf("%.2f%n",res);
}
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
n, k = map(int, input().split())
if k == 1:
print('%.2f' % (n * n / 2))
else:
m = k // 2
a = n / (m + 1)
b = n / (k - m + 1)
print('%.2f' % (a * b))
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
float s = 0.0;
if (k % 2 == 0) {
float parts = k / 2 + 1;
s = n / parts * n / parts;
}
else {
float partsw = (k - 1) / 2 + 1;
float partsl = (k + 1) / 2 + 1;
s = n * n / (partsw * partsl);
}
printf("%0.2f", s);
return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
第二题:01矩阵
题目描述
游游拿到了一个2行2列的01矩阵a,她每次操作可以交换a的相邻两个元素(同一行或者同一列均为相邻)。
游游想知道至少要多少次操作可以使得矩阵a变成矩阵b?
输入描述
共有t组询问。第一行输入一个正整数t<100,代表询问的次数。
每组询问共有4行,每行两个正整数。前两行用来表示矩阵a,后两行用来表示矩阵b。
2
0 1
1 0
1 0
0 1
0 0
0 0
1 1
1 1
输出描述
输出t行,每行输出一行答案。
如果无论如何都不能使得矩阵a变成矩阵b,则输出-1。
否则输出一个整数,代表操作的最小次数。
2
-1
思路
矩阵位置设为0,1,2,3
如果两个矩阵不同的位置为0个,答案为0
如果两个矩阵不同的位置为4个,答案为2
如果两个矩阵不同的位置为2个,
当为0、3或者1、2时,答案为2,
其余情况答案为1
代码
Java版本
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;
public class second {
static int[][] dist = {{-1,0},{1,0},{0,-1},{0,1}};
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
int[][] a = new int[][]{{sc.nextInt(),sc.nextInt()},{sc.nextInt(),sc.nextInt()}};
int[][] b = new int[][]{{sc.nextInt(),sc.nextInt()},{sc.nextInt(),sc.nextInt()}};
if(cout(a)!=cout(b)){
bw.write("-1");
continue;
}
int time = Integer.MAX_VALUE>>1;
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
time = Math.min(getTime(a, b,j,k),time);
}
}
if(time>=Integer.MAX_VALUE>>1)
bw.write("-1");
else
bw.write(Integer.toString(time));
if(i<t-1) bw.newLine();
}
bw.flush();
}
private static int cout(int[][] b) {
int res = 0;
for (int[] ints : b) {
for (int anInt : ints) {
if(anInt==1)res++;
}
}
return res;
}
private static int getTime(int[][] a, int[][] b, int x, int y) {
if(isVaild(a,b))
return 0;
if(x<0||x>=2||y<0||y>=2)
return Integer.MAX_VALUE>>1;
int res = Integer.MAX_VALUE>>1;
for (int[] ints : dist) {
swap(x,y,x+ints[0],y+ints[1],a);
res = Math.min(res,getTime(a,b,(y==1?x+1:x),(y==1?0:y+1))+1);
swap(x,y,x+ints[0],y+ints[1],a);
}
return res;
}
private static void swap(int x, int y, int x1, int y1, int[][] a) {
if(x1<0||x1>1||y1<0||y1>1)return;
int k = a[x][y];
a[x][y] = a[x1][y1];
a[x1][y1] = k;
}
private static boolean isVaild(int[][] a, int[][] b) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
if(a[i][j]!=b[i][j])
return false;
}
}
return true;
}
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
from collections import deque
def trans(m):
return m[0][0] * 1000 + m[0][1] * 100 + m[1][0] * 10 + m[1][1]
for _ in range(int(input())):
a = [list(map(int, input().split())), list(map(int, input().split()))]
b = [list(map(int, input().split())), list(map(int, input().split()))]
target = trans(b)
ans = -1
q = deque()
q.append((0, a))
seen = set([trans(a)])
while q:
price, m = q.popleft()
if trans(m) == target:
ans = price
break
nxts = [
[
[m[0][1], m[0][0]],
m[1]
],
[
m[0],
[m[1][1], m[1][0]]
],
[
[m[1][0], m[0][1]],
[m[0][0], m[1][1]]
],
[
[m[0][0], m[1][1]],
[m[1][0], m[0][1]]
]
]
for nxt in nxts:
v = trans(nxt)
if v not in seen:
q.append((price + 1, nxt))
seen.add(v)
print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
for (int i = 0; i < t; i++) {
vector<int> mata(4), matb(4);
for (int j = 0; j < 4; j++)
cin >> mata[j];
for (int j = 0; j < 4; j++)
cin >> matb[j];
int check = 0;
for (int j = 0; j < 4; j++) {
if ((mata[j] != 0 && mata[j] != 1) || (matb[j] != 0 && matb[j] != 1)) {
check = 1;
break;
}
}
if (check) {
cout << "-1" << endl;
continue;
}
int na1 = 0, nb1 = 0;
for (int j = 0; j < 4; j++) {
if (mata[j] == 1)
na1++;
if (matb[j] == 1)
nb1++;
}
if (na1 != nb1) {
cout << "-1" << endl;
continue;
}
if (na1 == 0 || na1 == 4) {
cout << "0" << endl;
continue;
}
vector<int> matemp(4);
int sum = 0;
for (int j = 0; j < 4; j++) {
matemp[j] = abs(mata[j] - matb[j]);
sum += matemp[j];
}
if (sum == 0) {
cout << "0" << endl;
}
else if ((matemp[0] == 1 && matemp[3] == 1) || (matemp[1] == 1 && matemp[2] == 1)) {
cout << "2" << endl;
continue;
}
else {
cout << "1" << endl;
continue;
}
}
return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
第三题:数字染色
题目描述
游游拿到的一个数组,其中一些数被染成红色,另一些数被染成蓝色。
游游每次操作,可以使得所有红色的数加1,或者可以使得所有蓝色的数减1。一共可以操作任意次。
游游希望最终数组的最大值减去最小值的差尽可能小,你能帮她求出这个差吗?
输入描述
输入包含多组测试用例,第一行一个正整数t,表示测试用例组数。
每组测试用例的第一行输入一个正整数n,代表数组的长度。
第二行输入n个正整数ai,代表游游拿到的数组。
第三行输入一个长度为n的、仅由’R’和’B’两种字符组成字符串,第i个字符为’R’代表第i个数染成红色,为‘B’代表染成蓝色。
1<n<2e3
1 < ai < 1e9
保证所有测试用例的n的总和不超过2e5
1
5
1 2 3 4 5
RRBRB
输出描述
3
说明:对红色的数和蓝色的数各操作一次,数组变成[2,3,2, 5,4],此时数组的最大值减最小值等于3。可以证明这个差无法小于3。
思路
贪心。因为红色值只能向上,蓝色值只能向下,只需要维护红色最大值最小值和蓝色最大值最小值。比如红色最大值更大的时候说明没有必要对红色进行操作,蓝色最小值最小的时候就没有必要对蓝色操作。否则要看将红色对齐到蓝色的代价和将蓝色对齐到红色的代价。
Java版本
public class fourth {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int t = Integer.parseInt(br.readLine());
for (int i = 0; i < t; i++) {
int n = Integer.parseInt(br.readLine());
String[] arr = br.readLine().split(" ");
String s = br.readLine();
int rmax = 0,rmin = Integer.MAX_VALUE;
int bmax = 0,bmin = Integer.MAX_VALUE;
for (int j = 0; j < n; j++) {
if(s.charAt(j)=='R'){
rmax = Math.max(Integer.parseInt(arr[j]),rmax);
rmin = Math.min(Integer.parseInt(arr[j]),rmin);
}else {
bmax = Math.max(Integer.parseInt(arr[j]),bmax);
bmin = Math.min(Integer.parseInt(arr[j]),bmin);
}
}
int max = Math.max(rmax - rmin, bmax - bmin);
max = Math.max(max,rmax-bmin);
bw.write(Long.toString(max));
bw.newLine();
}
bw.flush();
}
}
// vx公众号关注TechGuide 实时题库 闪电速递
代码
Python版本
for _ in range(int(input())):
n = int(input())
*a, = map(int, input().split())
c=input()
red = [a[i] for i in range(n) if c[i] == 'R']
blue = [a[i] for i in range(n) if c[i] == 'B']
if not red:
print(max(blue) - min(blue))
continue
if not blue:
print(max(red) - min(red))
continue
rmax, rmin = max(red), min(red)
bmax, bmin = max(blue), min(blue)
if rmax >= bmax:
if bmin <= rmin:
print(abs(rmax - bmin))
else:
print(abs(rmax - rmin))
else:
# 动红
ans = abs(bmax - min(bmin, rmin + bmax - rmax))
# 动蓝
ans = min(ans, rmax - min(bmin - bmax + rmax,rmin))
print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
for (int i = 0; i < t; i++) {
int n;
cin >> n;
vector<int> a(n);
for (int j = 0; j < n; j++)
cin >> a[j];
string s;
cin >> s;
int maxr = 0, maxb = 0, minr = 1e9 + 1, minb = 1e9 + 1;
for (int j = 0; j < n; j++) {
if (s[j] == 'R') {
maxr = max(a[j], maxr);
minr = min(a[j], minr);
}
else {
maxb = max(a[j], maxb);
minb = min(a[j], minb);
}
}
if (maxr == 0) {
cout << maxb - minb << endl;
continue;;
}
if (maxb == 0) {
cout << maxr - minr << endl;
continue;
}
if (maxr >= maxb && minr >= minb) {
cout << maxr - minb << endl;
continue;
}
int difr = maxr - minr;
int difb = maxb - minb;
cout << max(difr, difb) << endl;
}
return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
第四题:矩阵最大权值
题目描述
游游定义一个矩阵权值为:每一对相邻元素之和的总和。
例如,对于矩阵:
12
34
它的权值是(1+2)+(1+3)+(2+4)+(3+4)=3+4+6+7=20。
游游希望你构造一个nn的矩阵,矩阵中的元素为1到nn且每个数恰好出现一次。她希望最终矩阵的权值尽可能大。你能帮帮她吗?
由于矩阵可能过大,你不需要输出最终的矩阵,只需要输出这个最大权值即可。答案对1e9+7取模。
输入描述
一个正整数 n(2 <n <1e9)
input:
2
输出描述
矩阵的最大权值,对1e9+7取模。
20
思路
1,2,3,4只用计算2次
5到 4n-4 需要计算三次
4n-4+1到 n*n 需要计算4次
用等差数列求和
设求l,r
则(r-l+1)(l+r)/2
我们假设为ab/2
a和b都是1e9的,需要用大整数相乘
代码
Java版本
import java.util.Scanner;
public class third {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextInt();
long u = n*n;int mod = (int)1e9+7;
long len =( u-(n-1)*4)%mod;
long res = (((2*u-len+1))%mod*len*2)%mod;
long le = u - len - 4;
long prenum = (u-len+5);
if((le&1)==1){
prenum = (prenum>>1)%mod;
res = (res+(prenum*(le%mod)*3)%mod)%mod;
}else {
prenum = prenum%mod;
le = (le>>1)%mod;
}
res = (res+20+(prenum*(le%mod)*3)%mod)%mod;
System.out.println(res);
}
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
n = int(input())
arr = list(range(1, n * n + 1))
mod = int(1e9) + 7
central = (n - 2) * (n - 2)
edge = (n - 2) * 4
point = 4
def get(l, r):
return ((r + l) * (r - l + 1) // 2) % mod
ans = 2 * get(1, 4)
v = 5
ans = (ans + get(v, v + edge - 1) * 3) % mod
v += edge
ans = (ans + get(v, v + central - 1) * 4) % mod
print(ans)
关注TechGuide 实时题库 闪电速递