第一题:
按题意模拟。
public class Solution {
public boolean check(int[][] map,int val) {
for(int i=0;i<3;i++) {
if(map[i][0]==val&&map[i][1]==val&&map[i][2]==val)
return true;
if(map[0][i]==val&&map[1][i]==val&&map[2][i]==val)
return true;
}
if(map[0][0]==val&&map[1][1]==val&&map[2][2]==val)
return true;
if(map[0][2]==val&&map[1][1]==val&&map[2][0]==val)
return true;
return false;
}
public String tictactoe(int[][] moves) {
int[][] map=new int[3][3];
for(int i=0;i<moves.length;i++) {
if(i%2==0) {
map[moves[i][0]][moves[i][1]]=1;
}
else {
map[moves[i][0]][moves[i][1]]=2;
}
}
if(check(map,1))
return "A";
if(check(map,2))
return "B";
if(moves.length==9)
return "Draw";
return "Pending";
}
}
第二题:
解二元一次方程组,注意特判无解的情况。
public class Solution {
public List<Integer> numOfBurgers(int a, int b) {
int temp=a-2*b;
if(temp<0)
return new ArrayList<Integer>();
if(temp%2==1)
return new ArrayList<Integer>();
int x=temp/2;
int y=b-x;
if(x<0||y<0)
return new ArrayList<Integer>();
ArrayList<Integer> ans=new ArrayList<Integer>();
ans.add(x);
ans.add(y);
return ans;
}
}
第三题:
二维前缀和优化+暴力枚举。
public class Solution {
public int countSquares(int[][] g) {
int n=g.length;
int m=g[0].length;
int[][] dp=new int[n+1][m+1];
int[][] map=new int[n+1][m+1];
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++)
map[i][j]=g[i-1][j-1];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+map[i][j];
int ans=0;
for(int k=1;k<=Math.min(n, m);k++) {
for(int i=1;n-i+1>=k;i++) {
for(int j=1;m-j+1>=k;j++) {
if(dp[i+k-1][j+k-1]-dp[i+k-1][j-1]-dp[i-1][j+k-1]+dp[i-1][j-1]==k*k)
ans++;
}
}
}
return ans;
}
}
第四题:
暴力预处理+dp,dp[k][i][j]表示 i 到 j 这段子串分成k段的最小花费。(我的做法可能数据水的原因通过了,感觉应该会超时)
public class Solution {
public static final int INF=Integer.MAX_VALUE/16;
/*public static void main(String[] args) {
Solution s=new Solution();
int ans=s.palindromePartition("aabbc", 3);
System.out.println(ans);
}*/
public int calc(String s) {
int ans=0;
int i=0;
int j=s.length()-1;
while(i<j) {
if(s.charAt(i)!=s.charAt(j))
ans++;
i++;
j--;
}
return ans;
}
public int palindromePartition(String s, int k) {
int n=s.length();
s=" "+s;
int[][] w=new int[n+1][n+1];
for(int i=1;i<=n;i++)
w[i][i]=0;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
w[i][j]=calc(s.substring(i, j+1));
}
}
int[][][] dp=new int[k+1][n+1][n+1];
for(int i=0;i<dp.length;i++) {
for(int j=0;j<=n;j++) {
for(int x=0;x<=n;x++)
dp[i][j][x]=INF;
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
dp[1][i][j]=w[i][j];
}
}
for(int len=2;len<=n;len++) {
for(int l=1;l<=n-len+1;l++) {
int r=l+len-1;
for(int x=l;x<r;x++) {
for(int a=1;a<=x-l+1&&a<=k;a++) {
if(dp[a][l][x]==INF)
continue;
for(int b=1;b<=r-x&&a+b<=k&&b<=k;b++) {
if(a+b>k)
continue;
dp[a+b][l][r]=Math.min(dp[a+b][l][r],dp[a][l][x]+dp[b][x+1][r]);
}
}
}
}
}
return dp[k][1][n];
}
}