题目链接:牛客练习赛67
A:牛牛爱字符串
思路:直接模拟就可以了,但是字符串特别长,如果使用整形数组存数字,最终存不下。方案就是继续象存字符串一样存数字,由于是用的Java,所以可以直接使用BigInteger。
代码:
import java.util.Scanner;
import java.math.BigInteger;
public class Main{
public static void main(String[] args){
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
String str=cin.nextLine();
BigInteger ans[]=new BigInteger[str.length()+1];
int cnt=0;
boolean flag=false;
BigInteger numi=BigInteger.ZERO;
for(int i=0;i<str.length();i++){
char c=str.charAt(i);
int chr=str.charAt(i);
if(chr<48 || chr>57) {
if(flag) ans[++cnt]=numi;
flag = false;
numi=BigInteger.ZERO;
continue;
}else{
int num=c-'0';
numi=(numi.multiply(BigInteger.TEN)).add(BigInteger.valueOf(num));
flag=true;
}
}
if(flag) ans[++cnt]=numi;
if(cnt==0) System.out.println();
else{
for(int i=1;i<=cnt;i++){
if(i==1) System.out.print(ans[i]);
else System.out.print(" "+ans[i]);
}
System.out.println();
}
}
}
}
B:牛牛正在学习位运算
思路:这道题明白”&“运算会使得到的结果变小就很好做了,不多解释吧。
代码:
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
int T=cin.nextInt();
while(T-->0){
int n=cin.nextInt();
int a[]=new int[n+1];
int max_num=-999;
for(int i=0;i<n;i++){
a[i]=cin.nextInt();
if(a[i]>max_num) max_num=a[i];
}
System.out.println(max_num);
}
}
}
}
C:牛牛和牛妹玩博弈游戏
思路:虽然改变了下规则,但是结论还是一样的,总的石头数不能整除3,那么怎么取都会输掉,只要能整除3,那么就一直取保证剩下的也能整除3那么就必胜。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
int n=cin.nextInt();
while(n-->0){
int num=cin.nextInt();
if(num%3==1||num%3==2) System.out.println("Alan ");
else System.out.println("Frame ");
}
}
}
}
D:牛妹正在玩一个数列
思路:这个题求最小操作次数,那么可以考虑动态规划(dp),但是怎么dp呢,一维的dp显然不能满足条件,因为可以0变1,1变0,后面的状态是由这两个操作转化来的,因此加一个维度表示翻转前
i
i
i个需要的最小操作次数,也就是说
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0]表示将前
i
i
i个数翻转为0的最小操作数,
d
p
[
i
]
[
1
]
dp[i][1]
dp[i][1]则表示将前
i
i
i个数翻转为1的最小操作数,当我要对第
i
+
1
i+1
i+1个数进行翻转时候,就要分情况进行讨论了,如果第
i
+
1
i+1
i+1数是0,则
d
p
[
i
+
1
]
[
1
]
=
M
a
t
h
.
m
i
n
(
d
p
[
i
]
[
1
]
,
d
p
[
i
]
[
0
]
)
+
1
dp[i+1][1] = Math.min(dp[i][1],dp[i][0])+1
dp[i+1][1]=Math.min(dp[i][1],dp[i][0])+1(需要翻转一次),同时更新
d
p
[
i
+
1
]
[
0
]
=
d
p
[
i
]
[
0
]
dp[i+1][0] = dp[i][0]
dp[i+1][0]=dp[i][0](不用翻转),而如果第
i
+
1
i+1
i+1数是1,则
d
p
[
i
+
1
]
[
0
]
=
M
a
t
h
.
m
i
n
(
d
p
[
i
]
[
1
]
,
d
p
[
i
]
[
0
]
)
+
1
dp[i+1][0] = Math.min(dp[i][1],dp[i][0])+1
dp[i+1][0]=Math.min(dp[i][1],dp[i][0])+1,同时更新
d
p
[
i
+
1
]
[
1
]
=
d
p
[
i
]
[
1
]
dp[i+1][1] = dp[i][1]
dp[i+1][1]=dp[i][1]
import java.util.*;
import java.io.*;
import java.math.*;
public class Main{
public static void main(String []args){
Scanner cin = new Scanner(System.in);
while(cin.hasNext()){
int n = cin.nextInt();
int dp[][] = new int[n+1][2];
int a[] = new int[n];
for(int i=0;i<n;i++) a[i] = cin.nextInt();
dp[0][0] = a[0] == 0?0:1;
dp[0][1] = a[0] == 1?0:1;
for(int i=1;i<n;i++){
if(a[i]==0){
dp[i][1] = Math.min(dp[i-1][1],dp[i-1][0])+1;
dp[i][0] = dp[i-1][0];
}else{
dp[i][0] = Math.min(dp[i-1][0],dp[i-1][1])+1;
dp[i][1] = dp[i-1][1];
}
}
System.out.println(dp[n-1][0]);
}
}
}