1.握手问题
解题思路一
数学方法
50个人互相握手 (49+1)*49/2 ,减去7个人没有互相握手(6+1)*6/2
答案:1024
解题思路二
package 十五届;
public class Min {
public static void main(String[] args) {
int ans = 0;
for (int i = 1; i <= 50; i++) {
for (int j = i+1; j <= 50; j++) {
//排除掉7人的情况
if(!(i>=1&&i<=7 && j>=1&&j<=7)){
ans++;
}
}
}
System.out.println(ans);
}
}
2.小球反弹
解题思路:
针对前进的方向进行分解为x,y方向,去求解运动返回到左上角的时间,有了时间,即可利用时间来计算总路程,假设 x方向走了p个来回,y方向走了q个来回,经过了时间t,小球第一次回到原点
则时间*速率=路程 t*dx = 2px ,t*dy = 2qy,令一式/二式,得p/q= y/x*dx/dy = y*dx/x*dy ,利用gcd(求两个数的最大公约数)对分式p,q进行约分,进而得到约分后的p,q 则利用时间t=2px/dx,总路程 = t*(sqrt(15^2+17^2))
package 十五届;
import static java.lang.Math.sqrt;
public class 小球反弹 {
public static void main(String[] args) {
int x = 343720;
int y = 233333;
int dx = 15;
int dy = 17;
int p = y * dx;
int q = x * dy;
int g = gcd(p, q);
p /= g;
q /= g;
int t = 2 * p * x / dx;
double ans = t * sqrt(15 * 15 + 17 * 17);
//d答案输出两位小数
System.out.printf("%.2f", ans);
}
public static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
答案:1100325199.77
3.好数
解题思路
首先排除掉末位数,可以优化复杂度,满足条件后 在进一步检查偶数位是否为偶数,奇数位是否为奇数
package 十五届;
import java.util.Scanner;
public class 好数 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int ans = 0;
for (int i = 1; i <= n; i++) {
//局部优化:过滤数值结尾不符合条件的情况
if (i % 10 % 2 == 0) continue;
if (check(i)) ans++;//判断是否为好数
}
System.out.println(ans);
}
//检查x是否为好数
public static boolean check(int x) {
int cnt = 1; //记录位数
while (x > 0) {
int b = x % 10;
if (cnt % 2 == 1) {//是奇数位并且不是奇数
if (b % 2 != 1) return false;
} else if (b % 2 != 0) {//是偶数位并且不是偶数
return false;
}
cnt++;
x /= 10;
}
return true;
}
}
4.R格式
解题思路:
本题考察利用数组模拟高精度,
package 十五届;
import java.util.Scanner;
public class 高精度 {
public static void main(String[] args) {
int[] a = new int[(int) (2e3 + 10)];
String s = "";
int n = 0;
Scanner scanner = new Scanner(System.in);
s = scanner.nextLine();
n = scanner.nextInt();
StringBuffer stringBuffer = new StringBuffer(s);
stringBuffer.reverse();//反转字符串
int pos = s.indexOf('.');
stringBuffer.delete(pos, pos + 1);//把小数点删除,方便后续计算
int len = s.length();
for (int i = 0; i < len; i++) {
a[i + 1] = stringBuffer.charAt(i) - '0';
}
//高精度*低精度模板
for (int i = 1; i <= n; i++) {
//顺序扫描每一位,均*2
for (int j = 1; j <= len; j++) {
a[j] = a[j] * 2;
}
//再次扫描。处理进位和最高位
for (int j = 1; j <= len; j++) {
if (a[j] >= 10) {
a[j + 1]++;
a[j] %= 10;
if (j == len) len++;
}
}
}
//处理小数点后的第一位,进行四舍五入
if (a[pos] >= 5) {
a[pos + 1]++;
}
//倒序打印
for (int i = len; i >= pos+1; i--) {
System.out.print(a[i]);
}
}
}
第四题:宝石组合
题解·
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int a[100100], b[100100];
vector<int> vec[100100];
int n;
int main() {
ios::sync_with_stdio(false);
cout.tie(nullptr);
cin >> n;
int max_a = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[a[i]]++;
max_a = max(max_a, a[i]);
}
sort(a + 1, a + 1 + n);
for (int i = 2; i <= max_a; i++) {
for (int j = i; j <= max_a; j += i) {
for (int k = 1; k <= b[j]; k++) {
if (vec[i].size() >= 3) break;
vec[i].push_back(j);
}
}
}
for (int i = max_a; i >= 2; i--) {
if (vec[i].size() >= 3) {
cout << vec[i][0] << " " << vec[i][1] << " " << vec[i][2] << endl;
return 0;
}
}
cout << a[1] << " " << a[2] << " " << a[3] << endl;
return 0;
}