# leetcoe 第 147 场周赛 题解

A题:1137. 第 N 个泰波那契数

B题:1138. 字母板上的路径

‘!’ 会把在我们当前位置 (r, c) 的字符 board[r][c] 添加到答案中。

class Solution {
public:
string string_copy(string str,int time){
string res = "";
for(int i=0;i<time;++i)
res += str;
return res;
}
string oneToone(int src,int des){
string res = "";
int sr = src/5,dr = des/5;
if(sr == dr){//src和des在同一行
if(src < des)   return string_copy("R",des-src);
else    return string_copy("L",src-des);
}
else{
if(sr != 5 && dr != 5){
int dis = abs(sr-dr);
if(sr < dr){
res += string_copy("D",dis);
res += oneToone(src+dis*5,des);
}
else{
res += string_copy("U",dis);
res += oneToone(src-dis*5,des);
}
}
else{
if(sr == 5){//即src是z
res += 'U';//src先移动到z上面的位置
res += oneToone(src-5,des);
}
else{//des是z
//    res += string_copy("D",dr-sr-1);
//  res += string_copy("L",src%5);
res += oneToone(src,20);//先到达z上面的位置
res += "D";
}
}
}
return res;
}
string alphabetBoardPath(string target) {
//  return oneToone(0,11);
string res = "";
int last = 0;
for(int i=0;i<target.size();++i){
int now = target[i]-'a';
//   printf("last = %d,now = %d\n",last,now);
string temp = oneToone(last,now);
if(temp.size() != 0)
res += temp;
res += '!';
last = now;
}
return res;
}
};


C题:1139. 最大的以 1 为边界的正方形

1 <= grid.length <= 100
1 <= grid[0].length <= 100
grid[i][j] 为 0 或 1

class Solution {
public:
vector<vector<int>> vec;
int up[110][110];
int left[110][110];
int right[110][110];
int down[110][110];
int N,M;
void init(){
memset(up,0,sizeof(up));
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
memset(down,0,sizeof(down));
N = vec.size();
M = vec[0].size();
for(int i=0;i<N;++i){
for(int j=0;j<M;++j){
if(vec[i][j] == 0){
up[i][j] = left[i][j] = right[i][j] = down[i][j] = 0;
}
else{
int Count = 0;
int k = i;
while(--k >= 0 && vec[k][j] == 1)
Count++;
up[i][j] = Count;

Count = 0;
k = j;
while(--k >= 0 && vec[i][k] == 1)
Count++;
left[i][j] = Count;

Count = 0;
k = j;
while(++k < M && vec[i][k] == 1)
Count++;
right[i][j] = Count;

Count = 0;
k = i;
while(++k < N && vec[k][j] == 1)
Count++;
down[i][j] = Count;
}
}
}
}
void show(){
for(int i=0;i<N;++i){
for(int j=0;j<M;++j){
printf("%d %d %d %d %d %d\n",i,j,up[i][j],left[i][j],right[i][j],down[i][j]);
}
}
}
int largest1BorderedSquare(vector<vector<int>>& grid) {
vec = grid;
init();
int MaxSize = 0;
for(int i=0;i<N;++i){
for(int j=0;j<M;++j){
if(grid[i][j] == 1){
int now = 0;
int Max = min(right[i][j],down[i][j]);
while(now <= Max){
if(grid[i+now][j+now] == 1 && left[i+now][j+now] >= now && up[i+now][j+now] >= now){
MaxSize = max(MaxSize,(now+1)*(now+1));
}
now++;
}
}
}
}
//show();
return MaxSize;
}
};


D题:1140. 石子游戏 II

1 <= piles.length <= 100
1 <= piles[i] <= 10 ^ 4

dp[i][j] 表示i - n堆石子时，M = j 当前最大能拿走的石子.

∑ k = 1 2 ∗ j d p [ i ] [ j ] = m a x ( d p [ i ] [ j ] , s u m [ i ] − d p [ i + k ] [ m a x ( j , k ) ] \sum_{k=1}^{2*j}dp[i][j] = max(dp[i][j],sum[i]-dp[i+k][max(j,k)]

class Solution {
public:
int dp[110][110];
int sum[110];
int stoneGameII(vector<int>& piles) {
int N = piles.size();
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
for(int i=N-1;i>=0;--i)
sum[i] = sum[i+1] + piles[i];
for(int i=N-1;i>=0;--i){
for(int j=1;j<=N;++j){
for(int k=1;k<=2*j && i+k <= N;++k){
dp[i][j] = max(dp[i][j],sum[i]-dp[i+k][max(j,k)]);
}
}
}
return dp[0][1];
}
};

07-29 586
04-10 673

07-31 287
07-28 104
07-28 32
02-05 91
07-28 578
11-01 154