介绍
这一次,我能够在比赛中解决A到E,所以我会照原样解释。
让我们来看看。
A-最右边
问题陈述是这里
我使用了字符串的lastIndexOf。
class Main{
static final boolean autoFlush = false;
static final Library System = new Library(java.lang.System.in,java.lang.System.out,java.lang.System.err,autoFlush);
public static void main(String[] args){
//Sの受け取り
String S = System.in.next();
//aのindexを調べる
int ans = S.lastIndexOf("a");
//見つからなかったら-1なので別処理
System.out.println(ans>=0?ans+1:ans);
System.out.close();
}
}
提交后我注意到了,但是如果 S 是" "+S,则不必进行 ans+1。
B - 邻接表
问题陈述是这里
我记录了由 TreeMap 连接的城市(键是整数,值是 TreeSet)。
class Main{
static final boolean autoFlush = false;
static final Library System = new Library(java.lang.System.in,java.lang.System.out,java.lang.System.err,autoFlush);
public static void main(String[] args){
//N、Mの受け取り
int N = System.in.nextInt();
int M = System.in.nextInt();
//都市iの情報を、i-1をkeyとして保持
TreeMap<Integer,TreeSet<Integer>> list = new TreeMap<>();
for(int i=0;i<N;i++)list.put(i,new TreeSet<Integer>());
while(M-->0){
int A = System.in.nextInt();
int B = System.in.nextInt();
list.get(A-1).add(B);
list.get(B-1).add(A);
}
//都市1から順に出力
for(Integer key:list.keySet()){
System.out.print(list.get(key).size());
for(Integer num:list.get(key)){
System.out.print(' ');
System.out.print(num);
}
System.out.println();
}
System.out.close();
}
}
现在想来,我应该使用 ArrayList 而不是 TreeMap,但由于某种原因,我无法想出真正的东西。
C——前一个排列
问题陈述是这里
证明是官方评论我把它留给你,但寻找 $P[i]>P[i+1]$ 的最后一个位置,将 $P[i]$ 向前移动到一个 ArrayList,并在 $P[i]$ 下用 P[i] 替换最大的一个,然后用按降序排序的 ArrayList 替换将为您提供所需的序列。
class Main{
static final boolean autoFlush = false;
static final Library System = new Library(java.lang.System.in,java.lang.System.out,java.lang.System.err,autoFlush);
public static void main(String[] args){
//N、Pの受け取り
int N = System.in.nextInt();
int[] P = System.in.nextInt(N);
//一番後ろのP[i-1]>P[i]の場所を記録する変数
int index = -1;
for(int i=1;i<N;i++)
if(P[i-1]>P[i])
index = i-1;
//P[index]以降のものを記録するList
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=index;i<N;i++)
list.add(-P[i]); //降順で並べるために負数に変換
//ソート
Collections.sort(list);
//P[index]未満で最大のものを探す
int ind = System.overSearch(list,-P[index]);
//P[index]を更新
P[index] = -list.get(ind);
list.remove(ind);
//P[index+1]以降も更新
int j = 0;
for(int i=index+1;i<N;i++)
P[i] = -list.get(j++);
//空白区切りで出力
System.out.println(P," ");
System.out.close();
}
}
当我提交它时,我很担心,但我松了一口气,它似乎匹配。
D - 除以 2 或 3
问题陈述是这里
令 $a_1$ 为 $a$ 并且 $a_i(2 le i le N)$ 为 $A$。
要对齐 $a$ 和 $A$,转换为最大公约数 $g$ 需要最少的操作次数。所以,数一下找到$g$并将$rac{a}{g}$变为$1$的操作次数,以及将$rac{A}{g}$变为$1$的操作次数。这样很好。
class Main{
static final boolean autoFlush = false;
static final Library System = new Library(java.lang.System.in,java.lang.System.out,java.lang.System.err,autoFlush);
public static void main(String[] args){
//N、a_1を受け取り
int N = System.in.nextInt();
int a = System.in.nextInt();
//操作回数を記録する変数
int ans = 0;
for(int i=1;i<N;i++){
//a_iの受け取り
int A = System.in.nextInt();
//最大公約数を求める
int g = (int)System.gcd(a,A);
//初項をgに揃える回数を数える(a_iより後ろのものも揃えるのでiずつ加算する)
int subA = a/g;
while(subA%2==0){
subA /= 2;
ans += i;
}
while(subA%3==0){
subA /= 3;
ans += i;
}
//2か3で割り切れなかったら終了
if(subA!=1){
System.out.println(-1);
System.exit(0);
}
//初項更新
a = g;
//a_iも揃える回数を数える
subA = A/g;
while(subA%2==0){
subA /= 2;
ans++;
}
while(subA%3==0){
subA /= 3;
ans++;
}
//2か3で割り切れなかったら終了
if(subA!=1){
System.out.println(-1);
System.exit(0);
}
}
//答えの出力
System.out.println(ans);
System.out.close();
}
}
个人觉得没那么难。
E-往返
问题陈述是这里
我用 UnionFind 解决了这个问题。
当你找到.的正方形时,将其连接到上、下、左、右的.的正方形,并记录S周围的正方形。
后来,我与S连接并进行了判断。
class Main{
static final boolean autoFlush = false;
static final Library System = new Library(java.lang.System.in,java.lang.System.out,java.lang.System.err,autoFlush);
public static void main(String[] args){
//H、Wの受け取り
int H = System.in.nextInt();
int W = System.in.nextInt();
//UnionFind((i,j)はi*W+jとして扱う)
UnionFind uf = new UnionFind(H*W);
//グリッドの受け取り
char[][] map = System.in.nextCharArray(H);
//Sの座標を記録する変数
int startPoint = -1;
//S周りで`.`のマスを記録するList
ArrayList<Integer> list = new ArrayList<Integer>();
//`.`同士の連結とSの場所の特定、S周りの情報を調べる
for(int i=0;i<H;i++){
for(int j=0;j<W;j++){
if(map[i][j]=='.'){
if(i<H-1&&map[i+1][j]=='.')
uf.unite(i*W+j,(i+1)*W+j);
if(j<W-1&&map[i][j+1]=='.')
uf.unite(i*W+j,i*W+j+1);
if(i>0&&map[i-1][j]=='.')
uf.unite(i*W+j,(i-1)*W+j);
if(j>0&&map[i][j-1]=='.')
uf.unite(i*W+j,i*W+j-1);
}
if(map[i][j]=='S'){
startPoint = i*W+j;
if(i<H-1&&map[i+1][j]=='.')
list.add((i+1)*W+j);
if(j<W-1&&map[i][j+1]=='.')
list.add(i*W+j+1);
if(i>0&&map[i-1][j]=='.')
list.add((i-1)*W+j);
if(j>0&&map[i][j-1]=='.')
list.add(i*W+j-1);
}
}
}
//同じ集合に属しているとfalseが返ってくるようになっているのでfind |= uniteで調べられる
boolean find = false;
for(int num:list)
find |= !uf.unite(startPoint,num);
//答えの出力
System.out.println(find?"Yes":"No");
System.out.close();
}
}
我也很快想到了这个。还不错···。
想法
A、B:容易
C:很高兴你很快想到了它
D:对D来说容易……?
E:第一次使用UF
这就是它的感觉。
这是一场需要快速解决方案的比赛,因为我觉得这次很容易。
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308633156.html