想参加字节跳动2019夏令营
在网上看字节跳动夏令营的笔试题(正在更新)
第一题:
输入16进制数(1,2…f…)组成的矩阵,由左上角开始,到右下角,只能向右或下走,找出另走过的数的乘积的16进制数后缀0最少的方法。
就是一道简单的dp题把,主要注意十六进制(其实十六进制完全可以当作十进制处理,就是把进位改成16就好了)
#include<iostream>
using namespace std;
int nn[100][100];
int dp[100][100];
void myin(int n, int m)//输入函数
{
char c;
for(int i = 0; i<m; i++)
{
for(int j = 0; j<n; j++)
{
cin >> hex >> nn[i][j];
}
}
}
int pls(int i, int j, int a, int b)//计算0的增数
{
int plss = 0;
int miu = nn[i-a][j-b] * nn[i][j];
while(1)
{
if(miu % 16 == 0)
{
plss++;
miu /= 16;
}
else
break;
}
nn[i][j] = miu;
return plss;
}
int main()
{
int n,m;
cin >> n >> m;
myin(n, m);
for(int i = 0; i<m; i++)
{
for(int j = 0; j<n; j++)
{
if(i == 0 && j == 0)
dp[i][j] = 0;
else if(i == 0)
dp[i][j] = dp[i][j - 1] + pls(i,j,0,1);
else if(j == 0)
dp[i][j] = dp[i - 1][j] + pls(i,j,1,0);
else
dp[i][j] = dp[i][j - 1]<dp[i - 1][j]?(dp[i][j - 1] + pls(i,j,0,1)):(dp[i - 1][j] + pls(i,j,1,0));
}
}
printf("乘积矩阵:\n");
for(int i = 0; i<m; i++)
{
for(int j = 0; j<n; j++)
{
printf("%x ",nn[i][j]);
}
printf("\n");
}
printf("状态矩阵:\n");
for(int i = 0; i<m; i++)
{
for(int j = 0; j<n; j++)
{
printf("%d ",dp[i][j]);
}
printf("\n");
}
printf("最小末尾0:%d\n",dp[n-1][m-1]);
}
第二题:
找矩阵有几组1,1的周围八格有1的话,视为同一组。
dfs8个方向找1(比较懒直接找8个方向,好像只用找5个方向就ok了),找过的位置改成0防止再找一遍
#include <iostream>
using namespace std;
int n,m;
int nn[100][100];
int z = 0;
int myin(int n, int m)
{
for(int i = 0; i<n; i++)
for(int j = 0; j<m; j++)
cin >> nn[i][j];
}
void dfs(int p,int q,bool ifgroup)
{
if(p<n && q<m && p>=0 && q>=0)
{
if(nn[p][q])
{
nn[p][q] = 0;
if(ifgroup)
{
z++;
}
dfs(p,q+1,0);
dfs(p+1,q+1,0);
dfs(p+1,q,0);
dfs(p+1,q-1,0);
dfs(p,q-1,0);
dfs(p-1,q-1,0);
dfs(p-1,q,0);
dfs(p-1,q+1,0);
}
if(ifgroup)
{
if(q<(m-1)) dfs(p,q+1,1);
else dfs(p+1,0,1);
}
}
else
return;
}
int main()
{
cin >> n >> m;
myin(n,m);
dfs(0,0,1);
cout << z << endl;
}