今天看了两节二分的网课,感觉蛮好玩的,但是关于二分mid向上取整向下取整还不是很懂,我决定等做题的时候再回去看一遍网课。
今天写了几道递归分治的题目。
一,小q的数列
开始我想了很久,还把1~100的数字都算了出来,发现不出什么规律,后来我去看了下题解,发现这个原来和二进制有关,我应该敏感一点的,看到那个除以2和%2,其实也和自己做的题目少,所以信心不足,总觉得肯定是我不懂的知识点,我看肯定做不来。还是要多刷题。
这是完整的代码:
#include<iostream>
using namespace std;
#define ll long long
//返回x的二进制中的最后一个1的值,比如100000100,返回100
ll lowbit(ll x){
return x&(-x);
}
int main(){
int t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
ll res=0;
while(n) n-=lowbit(n),res++;
cout<<res<<' ';
ll x=1;
while(res--) x*=2;
cout<<x-1<<endl;
}
return 0;
}
二,The Biggest Water Problem
这道题是一道简单的题目,但是我犯了一个弱智的错误:
就是这样输出的结果不一样,后来我去问了一下别人,这是编译器的问题,至于我每次都超时是有别的原因,那就是sum的值我要给它赋初值为0,不然它每次都会累加。我加上int sum=0;马上就AC了。
三,第k小数
这道题没有任何难度,但是还是想写到笔记里面是因为那个快读。
一开始一直看不懂这个快读是什么意思。然后我就直接用scanf提交了
结果可想而知,运行超时,后来我就cv了那个快读,没有想到,居然过了。
#include<iostream>
#include<algorithm>
using namespace std;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
int main()
{
int t,n,k,i;
int a[5000010];
cin>>t;
while(t--)
{
cin>>n>>k;
for(i=0;i<n;i++)
a[i]=read();
sort(a,a+n);
printf("%d\n",a[k-1]);
}
return 0;
}
我认为这个快读的代码要稍微记一下。
最后复习了一下二叉树的四种遍历,为后面的题目做准备。