二叉树最近公共祖先、求连续最大比特数
题目要求:
<1>.给定int a和int b作为结点编号
<2>.返回a和b的最近公共祖先
解题思路:
暂无,没做出来
代码示例:
暂无
题目要求:
<1>.输入一个数,将其转为二进制数
<2>.输出1连续出现的最大次数
解题思路:
<1>.按照之前做过的进制转换,写出进制转换的代码
<2>.按照之前做过的找出最大连续数字串的方法,统计1最大的连续的出现次数
之前写过的代码多看看,写过的再想用还是不太熟…
代码示例:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string Func(int a,int b)
{
string s;
string table{0123456789ABCDEF};
bool symbol=false;
if(a<0)
{
symbol=true;
a=0-a;
}
while(a!=0)
{
s+=table[a%b];
a/=b;
}
if(symbol==true)
{
s+='-';
}
reverse(s.begin(),s.end());
return s;
}
int main()
{
int A;
while(cin>>A)
{
string s=Func(A,2);
int count=0;
int max=0;
for(int i=0;i<s.length();++i)
{
while(s[i]==1)
{
count++;
i++;
if(i==s.size())
{
break;
}
}
if(count>=max)
{
max=count;
count=0;
}
}
cout<<max<<endl;
}
system("pause");
return 0;
}
反思:
<1>.题目中描述的子节点与父节点的关系为root=child/2;
<2>.所以当a!=b时,循环比较a,b,让大的数/=2
<3>.当a,b相等时,得到的就是最近公共祖先的编号
正确代码示例:
class LCA
{
public:
int getLCA(int a, int b)
{
while(a!=b)
{
if(a>b)
{
a/=2;
}
else
{
b/=2;
}
}
return a;
}
};
优先使用更简洁的方法,但是位运算好难理解…
正确代码示例:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int count=0;
int maxcount=0;
while(n)
{
//获取当前位的二进制值
if(n&1)
{
++count;
maxcount=max(count,maxcount);
}
else
{
count=0;
}
n=n>>1;
}
cout<<maxcount<<endl;
}
return 0;
}
二进制插入、组成偶数的两个最近的素数
题目要求:
<1>.给定两个32位整数m和n,将n的二进制数位插到m中的i~j位
<2>.示例:1024 19 2 6
<3>.输出插入后到数1100
解题思路:
<1>.1024 10000000000
<2>.11 10011
<3>.插到第2~6位 10001001100
<4>.输出这个新的数
代码示例:
class solution
{
public:
int binInsert(int n,int m,int j,int i)
{
m=m<<j;
return n|m;
}
};
题目要求:
<1>.任意一个偶数都可以由两个素数组成,输入一个偶数
<2>.输出两个素数(差值最小)
<3>.示例:20 —>7 13
解题思路:
<1>.先写一个判断是不是素数的函数
<2>.从中查找才能差值最小
<3>.找到一个之后另一个是输入的数减去找到的这个数
<4>.但是要确保另一个也是素数
代码示例:
#include<iostream>
#include<math.h>
using namespace std;
bool isprime(int a)
{
int b=sqrt(a);
for(int c=2;c<=b;++c)
{
if(a%c==0)
{
return false;
}
}
return true;
}
int main()
{
int m;
while(c>>m)
{
for(int i=m/2;i>=2;--i)
{
if(isprime(i)==true&&isprime(m-i)==true)
{
cout<<i<<endl;
cout<<m-i<<endl;
break;
}
}
}
return 0;
}
参数解析、跳石板
题目要求:
<1>.输入一行字符串,可以有空格
<2>.输出参数个数,分解后的参数(每个参数占一行)
解题思路:
<1>.以空格和双引号为间隔,找出参数保存到string里
<2>.把所有的参数保存到vector中,输出vector的size,遍历vector打印
代码示例:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
string s;
while(getline(cin,s))
{
bool flag=false;
vector<string> v;
string s1;
for(int i=0;i<s.size();++i)
{
if(flag)
{
if(s[i]!='"')
{
s1+=s[i];
}
else
{
flag=false;
}
}
else
{
if(s[i]==' ')
{
v.push_back(s1);
s1="";
}
else if(s[i]=='"')
{
flag=true;
}
else
{
s1+=s[i];
}
}
}
v.push_back(s1);
cout<<v.size()<<endl;
for(auto e:v)
{
cout<<e<<endl;
}
}
return 0;
}
题目要求:
<1>.从当前数字石板跳到目标石板
<2>.每次跳的步数为目标石板的一个约数
<3>.不能到达返回-1,可以到达返回需要的最少步数
据说是网易2017年真题,大厂就这么难吗?
我能说我看答案都没看懂吗??
这可怎么办?
正确代码示例:
**代码示例:**
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void DivNum(int n,vector<int>& divNum)
{
for(int i=2;i<=sqrt(n);++i)
{
if(n%i==0)
{
divNum.push_back(i);
if(n/i!=i)
{
divNum.push_back(i);
}
}
}
}
int Jump(int N,int M)
{
//储存到达此stepNum点的步数,初始N为一步,从N到M为一步
vector<int> stepNum(M+1,0);
stepNum[N]=1;//最后返回的时候需要减一
for(int i=N;i<M;++i)
{
vector<int> divNum;
if(stepNum[i]==0)
{
continue;
}
//求出所有可以走的步数 ,存到divNum中
DivNum(i,divNum);
for(int j=0;j<divNum.size();++j)
{
if((divNum[j]+1)<=M&&stepNum[divNum[j]+1]!=0)
{
stepNum[divNum[j]+1]=min(stepNum[divNum[j]+1],stepNum[i]+1);
}
else if((divNum[j]+1)<=M)
{
stepNum[divNum[j]+1]=stepNum[i]+1;
}
}
if(stepNum[M]==0)
{
return -1;
}
else
{
return stepNum[M]-1;
}
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
cout<<Jump(n,m)<<endl;
}
system("pause");
return 0;
}
计算天数、幸运的袋子
题目要求:
<1>.输入三行,分别为年月日
<2>.输出当前日期在这一年中的天数
解题思路:
<1>.这都已经不知道写过多少遍了,完善日期类的时候就写过了
<2>.判断是否是闰年,闰年2月29天
<3>.遍历月份,获取每月天数,累加到sum
<4>.把最后一个月的当前天数累加到sum
<5>.输出sum
代码示例:
#include<iostream>
#include<vector>
using namespace std;
bool isYear(int year)
{
if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0)
{
return true;
}
return false;
}
int GetMonthDay(int year, int month)
{
vector<int> days{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (isYear(year) == true)
{
days[2] = 29;
}
return days[month];
}
int Description(int year, int month, int day)
{
int sum = 0;
for (int i = 1; i < month; ++i)
{
sum += GetMonthDay(year, i);
}
sum += day;
return sum;
}
int main()
{
int year, month, day;
while (cin >> year >> month >> day)
{
cout << Description(year, month, day) << endl;
}
system("pause");
return 0;
}
题目要求:
<1>.幸运的袋子就是所有数的和大于所有数的乘积
<2>.现在可以适当从袋子里移除一些球(可以移除0个,但是别移除完)
<3>.求出移植之后袋子还是幸运的的个数
我把题意理解错了,我以为一次只能移除一个,但是不是这样的
所以这个题我不会,那20%通过是题目送的…
反思:
深度优先遍历,暂时还没了解到…慢慢弄懂…
正确代码示例:
#include<iostream>
#include<algorithm>
using namespace std;
int GetLuckyPacket(int x[],int n,int pos,int sum,int multi)
{
int count=0;
for(int i=pos;i<n;++i)
{
sum+=x[i];
multi*=x[i];
if(sum>multi)
{
count+=1+GetLuckyPacket(x,n,i+1,sum,multi);
}
else if(x[i]==1)
{
count+=GetLuckyPacket(x,n,i+1,sum,multi);
}
else
{
break;
}
sum-=x[i];
multi/=x[i];
while(i<n-1&&x[i]==x[i+1])
{
i++;
}
}
return count;
}
int main()
{
int n;
while(cin>>n)
{
int x[n];
for(int i=0;i<n;++i)
{
cin>>x[i];
}
sort(x,x+n);
cout<<GetLuckyPacket(x,n,0,0,1)<<endl;
}
return 0;
}
二进制1的个数、手套
题目要求:
输入一个数,求出二进制中1出现的次数
解题思路:
<1>.最近的题都是第一道很简单,第二道很难…起码我觉得是…
<2>.前面做过类似的题,while(n),里面每次n>>=1,就遍历了n的每一位
<3>.n&1,就取出了每一位的值,判断是否和1相等,相等count++
<4>.输出count的值
代码示例:
#include<iostream>
using namespace std;
int findNumberOf1(int num)
{
int count=0;
while(num)
{
if((num&1)==1)
{
count++;
}
num>>=1;
}
return count;
}
int main()
{
int n;
while(cin>>n)
{
cout<<findNumberOf1(n)<<endl;
}
system("pause");
return 0;
}
算法基础太差…无从入手的感觉…
题目要求:
<1>.题目要求呢…没记下…因为题我根本就没读懂
解题思路:
<1>.没有思路…
代码示例:
暂无
反思:
对于非零递增序列,a1,a2…an,要想最终取值覆盖每个种类n=sum(a1…an)-a1+1,(也就是总数减去最小值之后+1),所以对于左右手手套颜色都有数量的序列,想要覆盖每一种颜色,则最小数量leftsum=左边数量和-左边最小值+1,rightsum=右边数量和-右边最小值+1,而对于有0存在的,则需要做累加,保证覆盖每一种颜色
正确代码示例:
class Gloves
{
public:
int findMinimum(int n, vector<int> left, vector<int> right)
{
int left_sum = 0, left_min = INT_MAX;
int right_sum = 0, right_min = INT_MAX;
int sum = 0;
//遍历每一种颜色的左右手套序列
for (int i = 0; i < n; i++)
{
//对于有0存在的颜色手套,累加
if (left[i] * right[i] == 0)
{
sum += left[i] + right[i];
}
//对于左右手都有的颜色手套,执行累加-最小值+1
//找到最小值和总数
else
{
left_sum += left[i];
right_sum += right[i];
left_min = min(left_min, left[i]);
right_min = min(right_min, right[i]);
}
}
//结果为有左右都有数量的手套序列的结果+有0存在的手套数+最后再加一肯定就能保证了
return sum + min(left_sum - left_min + 1, right_sum - right_min + 1) + 1;
}
};