介绍
这一次,ABD将在比赛期间发布,CEF将在比赛结束后发布。
让我们来看看。
啊找高桥
问题陈述是这里
通常,您应该从一开始就搜索最大的那个。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args){
//Nの受け取り
int N = System.in.nextInt();
//maxは最大値、ansはその位置を記録する
int max = 0;
int ans = 0;
//先頭から最大値を探す
for(int i=1;i<=N;i++){
int H = System.in.nextInt();
//最大値更新
if(max<H){
max = H;
ans = i;
}
}
//答えの出力
System.out.println(ans);
System.out.close();
}
}
没问题。
B-ABC-DEF
问题陈述是这里
由于每个值都很大,所以可以通过提前转换太多和计算过程中转换太多来正确计算。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args){
//mod
int mod = 998244353;
//A~Fをmodをとりながら受け取り
long A = System.in.nextLong()%mod;
long B = System.in.nextLong()%mod;
long C = System.in.nextLong()%mod;
long D = System.in.nextLong()%mod;
long E = System.in.nextLong()%mod;
long F = System.in.nextLong()%mod;
//こまめにmodをとりながら計算
long temp1 = (A*B%mod)*C%mod;
long temp2 = (D*E%mod)*F%mod;
//差を出力(temp1-temp2が負数になってしまう可能性があるので+modをしている)
System.out.println((temp1-temp2+mod)%mod);
System.out.close();
}
}
这看起来也不错。
C - 数平方
问题陈述是这里
我在做什么AngrySadEight 的评论是相同的
考虑$d1到d6$的组合很麻烦,所以我把它们放在一个数组中,并在比较之前对它们进行排序。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args){
//#の位置を記録するList
ArrayList<Point> list = new ArrayList<Point>();
//各マスを見ていく
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
char c = System.in.nextChar();
//#なら格納
if(c=='#')
list.add(new Point(i,j));
}
}
//便宜上Nに記録
int N = list.size();
//答えを記録
int count = 0;
//重複しないようにしながら四つの#を選ぶ
for(int i=0;i<N;i++)for(int j=i+1;j<N;j++)for(int k=j+1;k<N;k++)for(int l=k+1;l<N;l++){
//便宜上p1~p4として別変数に
Point p1 = list.get(i);
Point p2 = list.get(j);
Point p3 = list.get(k);
Point p4 = list.get(l);
//各#間の距離を全部計算
int[] d = new int[6];
d[0] = dist(p1,p2);
d[1] = dist(p1,p3);
d[2] = dist(p1,p4);
d[3] = dist(p2,p3);
d[4] = dist(p2,p4);
d[5] = dist(p3,p4);
//ソートして辺と対角線が条件を満たしていたらcountに1を足す
System.sort(d);
if(d[0]==d[3]&&d[4]==d[5]&&2*d[0]==d[5])
count++;
}
//答えの出力
System.out.println(count);
System.out.close();
}
//距離の二乗を返すメソッド
public static int dist(Point p1,Point p2){
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
}
//x、y座標を記録する用の構造体
class Point{
int x;
int y;
public Point(int x,int y){
this.x = x;
this.y = y;
}
}
表演的时候很着急,写了脏代码……(提交结果)。
我不擅长图形问题...
D - 又一个递归函数
问题陈述是这里
用记忆递归解决。
我认为在 HashMap 或 TreeMap 中记录时解决会更好。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args){
//Nの受け取り
long N = System.in.nextLong();
//再帰して答えを出力
System.out.println(dfs(N));
System.out.close();
}
//メモ用のmap
static HashMap<Long,Long> memo = new HashMap<Long,Long>();
//再帰メソッド
public static long dfs(long n){
//終点判定
if(n==0)
return 1;
//メモにあるならそれを返す
if(memo.containsKey(n))
return memo.get(n);
//メモに無ければ再帰して答えを求める
long ans = dfs(n/2);
ans += dfs(n/3);
//メモに残してから答えを返す
memo.put(n,ans);
return ans;
}
}
听起来比较容易……?
图片 - Sugoroku 4
问题陈述是这里
我用街道数解决了到达平方 $N$ 的问题。
然后它可以作为一个简单的动态规划来解决。过渡如下,其中$dp[i][j]$是$j$中第$i$转的街道数量($k$是结果,$j$是当前位置)。
如果 $k+j > N$
$index = 2 次 N-(k+j)$,
如果$k+jle N$
由于 $index = k+j$,
$dp[i][索引] = dp[i][索引]+dp[i-1][j]$
$(1 le k le M,0 le j lt N)$
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args){
//mod
int mod = 998244353;
//N、M、Kの受け取り
int N = System.in.nextInt();
int M = System.in.nextInt();
int K = System.in.nextInt();
//dp[i][j]:i回回した時にjにいる通り
int[][] dp = new int[K+1][N+1];
//初期値設定
dp[0][0] = 1;
//遷移
for(int i=1;i<=K;i++){
for(int j=0;j<N;j++){
for(int k=1;k<=M;k++){
int index = k+j>N?2*N-(k+j):k+j;
dp[i][index] += dp[i-1][j];
dp[i][index] %= mod;
}
}
}
//全通り数
long full = System.modPow(M,K,mod);
//Nに到達できる通り数
long count = 0;
//総和を求める
for(int i=1;i<=K;i++){
count *= M;
count %= mod;
count += dp[i][N];
count %= mod;
}
//fullの逆元をかけてmodをとれば求めたい答えになる
System.out.println((count*System.modPow(full,mod-2,mod))%mod);
System.out.close();
}
}
您可以将其视为至少达到 $N$ 一次的街道数量,因此您需要将 $dp[i][N]$ 乘以 $M^{N-i}$ 并取总和(我用这个 I没有意识到它,也没有在比赛中解决它......)。
F - 擦除子数组
问题陈述是这里
我使用动态编程解决了它。
那些没有在从$dp0[i][j]$ 到$i$th 的最小操作数中选择当前元素的人,
$dp1[i][j]$ 已转换如下,当前元素从创建 $j$ 的最小操作数中选择,最多为 $i$。
$dp0[i+1][j] = mathrm{min}(dp0[i][j],dp1[i][j]+1)$
$dp1[i+1][j] = mathrm{min}(dp0[i][j-a[i]],dp1[i][j-a[i]])$
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args){
//N、M、aの受け取り
int N = System.in.nextInt();
int M = System.in.nextInt();
int[] a = System.in.nextInt(N);
//上記参照
int[][] dp0 = new int[N+1][M+1];
int[][] dp1 = new int[N+1][M+1];
//適当に大きな値を
int max = (int)1e6;
//初期値設定
for(int i=0;i<=N;i++){
Arrays.fill(dp0[i],max);
Arrays.fill(dp1[i],max);
}
dp1[0][0] = 0;
//遷移
for(int i=1;i<=N;i++){
for(int j=0;j<=M;j++){
dp0[i][j] = Math.min(dp0[i-1][j],dp1[i-1][j]+1);
if(j>=a[i-1])
dp1[i][j] = Math.min(dp0[i-1][j-a[i-1]],dp1[i-1][j-a[i-1]]);
}
}
//1~Mについて答えを求めて出力
for(int i=1;i<=M;i++){
int ans = Math.min(dp0[N][i],dp1[N][i]);
System.out.println(ans>=max?-1:ans);
}
System.out.close();
}
}
嗯……我尝试再次解决时确实如此,但在实际表演中很难想到……
想法
A、B:比较容易
C:非常麻烦。
D:我觉得轻松一点
E:我不擅长概率……
F:我还以为是动态编程,但是我没弄懂……
这就是它的感觉。
完成 4...sad... 后,速率图开始形成向下的斜坡
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308632070.html