4308. 组合字符串
比赛时没有通过,思路是对的(经过观察发现,s2字符串只会取第一个字符,而s1字符串一定取第一个字符,后面的字符取到小于s2字符串第一个字符的地方),但是遗漏了等于号。
aw比awc字典序要小,所以当找到s1中除第一个字符外,不小于s2中第一个字符的字符时退出循环。找到等于的也不继续向下找了,并且不要这个等于的。
import java.util.Scanner;
public class Main_1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s1 = scanner.next();
String s2 = scanner.next();
int i;
for (i = 1; i < s1.length(); i++) {
if (s1.charAt(i) >= s2.charAt(0)) {// 漏了等于号!!!!!!
// System.out.println(s1.charAt(i));
break;
}
}
System.out.print(s1.subSequence(0, i));
System.out.print(s2.charAt(0));
}
}
y总思路:枚举。
y总代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string a, b;
cin >> a >> b;
string res(20, 'z');
for (int i = 1; i <= a.size(); i ++ )
for (int j = 1; j <= b.size(); j ++ )
res = min(res, a.substr(0, i) + b.substr(0, j));
cout << res << endl;
return 0;
}
(枚举虽简单,但是我不敢用呀,超时咋办呀?但是大神信手拈来,因为他知道不会超时,那么借此学一下判断是否超时)
就这个题而言枚举也就是10*10的数据量,一看就不会超时。
先留在这吧,没搜到判断超时的方法。。。。。。
4309. 消灭老鼠
这个题,一上来就有思路(求每一个点与给定点形成直线的斜率,然后利用set判重),因为21年蓝桥杯我做过和这个差不多的题,但是还是还是没有AC。我就想,我去,我蓝桥杯是不是也这样。虽然已经比完了。
虽然我设成了double,但是据y总言,除法会出现精度问题,也有小伙伴说精度调到小数点后十位可以AC。
y总思路:
利用STL中的pair,存放(x-x0,y-y0).即分别存放斜率的分子和分母,不必作除法,当然结果应该约分化为最简。考虑到可能出现(-2,3)与(2,-3)的情况(这两个应该是一个,只是符号不同),我们规定如果y出现负号,那么把负号给x。
自己写的时候调了好久,一直不AC,还是许多细节问题
int a = xx;
int b = yy;
if (b > a) {
int temp = b;
b = a;
a = temp;
}
int d = gcd(a, b);
xx = xx / d;
yy = yy / d;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main_2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int x = scanner.nextInt();
int y = scanner.nextInt();
// node[] s = new node[n];
Set<String> set = new HashSet<String>();
for (int i = 0; i < n; i++) {
int xx = scanner.nextInt();
int yy = scanner.nextInt();
xx -= x;
yy -= y;
int a = xx;
int b = yy;
if (b > a) {
int temp = b;
b = a;
a = temp;
}
int d = gcd(a, b);
xx = xx / d;
yy = yy / d;
if (yy < 0) {
xx = -xx;
yy = -yy;
}
String string = xx + "_" + yy;
set.add(string);
}
System.out.println(set.size());
}
private static int gcd(int xx, int yy) {
// TODO Auto-generated method stub
return yy != 0 ? gcd(yy, xx % yy) : xx;
}
}
4310. 树的DFS
这个比赛时我直接一行代码也没敲,因为纯纯看不懂题目。
y总思路:
只能说绝!!
树的dfs遍历,要求某一棵子树的按照dfs便利的第k个节点的编号。那么我用两个数组q[i],p[i]。q[i]表示编号为i的节点在dfs便利中的序列号,p[i]表示在dfs遍历中序列号为i的节点在树中的编号,也就是这两个数组可以互相表示的。那么我要求以i为根节点的子树中在dfs中第k个被遍历到的数(包括j本身),可以通过q[p[i] + k - 1]表示。同时为了判断改节点是否存在,设置一个数组size[i]表示以i为根节点的子树的节点数(包括i本身),当k > size[i],时该节点不存在。
java的一个不好处,同样的思路,他比c++耗时,所以我在用Scanner输入时超时了,最后使用BufferedReader输入,代码才可以AC。
我的代码和思路都是仿照y总的。不得不说,dfs的代码好绝。单独欣赏一下。
private static void dfs(int i) {
// TODO Auto-generated method stub
size[i] = 1;
q[i] = num;
p[num] = i;
num++;
for (Integer e : v.get(i)) {
dfs(e);
size[i] += size[e];
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Vector;
public class Main_3 {
static int[] p;
static int[] q;
static int num;
static int size[];
static Vector<Vector<Integer>> v = new Vector<Vector<Integer>>();
public static void main(String[] args) throws IOException {
// Scanner scanner = new Scanner(System.in);//时间超限
// int n = scanner.nextInt();
// int k = scanner.nextInt();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
String[] strings = reader.readLine().split(" ");
int n = Integer.parseInt(strings[0]);
int k = Integer.parseInt(strings[1]);
p = new int[n + 1];
q = new int[n + 1];
size = new int[n + 1];
// Vector[] vv = new Vector()[3];
for (int i = 0; i < n + 1; i++) {
Vector<Integer> vv = new Vector<Integer>();
v.add(vv);
}
strings = reader.readLine().split(" ");
int index = 0;
for (int i = 2; i < n + 1; i++) {
// int x = scanner.nextInt();
// Integer x = reader.read();
v.get(Integer.parseInt(strings[index++])).add(i);
}
dfs(1);
while (k > 0) {
// int kk = scanner.nextInt();
// int xx = scanner.nextInt();
strings = reader.readLine().split(" ");
int kk = Integer.parseInt(strings[0]);
int xx = Integer.parseInt(strings[1]);
if (size[kk] < xx) {
// System.out.println("-1");
writer.write("-1\n");
} else {
// System.out.println(p[q[kk] + xx - 1]);
writer.write(p[q[kk] + xx - 1] + "\n");
}
k--;
}
writer.flush();
writer.close();
reader.close();
}
private static void dfs(int i) {
// TODO Auto-generated method stub
size[i] = 1;
q[i] = num;
p[num] = i;
num++;
for (Integer e : v.get(i)) {
dfs(e);
size[i] += size[e];
}
}
}
提一下,我之前为什么没读懂题。有一个样例是这样的
9 6 1 1 1 3 5 3 5 7 3 1 1 5 3 4 7 3 1 8 1 9
我按照他没有画出树来,我画成了右边的,明显不对,然后我就懵了,唉,实际应该是左边的,
总结一下学到了啥:
首先y总代码好简洁啊!!!!嘿嘿
熟悉树的dfs便利,并了解到qp两数组的优越性。
了解了java中的pair是Map.Entry。
学会了在java中用缓存输入,提高速度
学会了一种避免除法的方式。