最近图论的题只做了两道,最短路径的算法的思想是明白的,但写代码时总会感到力不从心,可能做得不多,对代码比较生疏。接下来总结一下近期做题中学到的知识。
一.
一般判断素数一个个直接判断会超时,所以要用埃氏筛法并且打表
bool c[100000001];
void prime(int b) {
memset(c, true, sizeof(c));
c[1]=false;
int n=sqrt(b);
for (int i=2;i<=n;i++) {
if (c[i]) {
for (int j=2;j<=b/i;j++)
c[i*j]=false;
}
}
}
判断回文数
bool ishws(int num) {
int temp=num,ans=0;
while (temp!=0) {
ans=ans*10+temp%10;
temp/=10;
}
if (ans==num)
return true;
else
return false;
}
二.
今天做的二分的一道题
题意:现在的正确率是 a/b , 要达到c/d ,可以进行任意次的正确与非正确提交,求最小的提交次数能够得到c/d, 如果不能得到 s输出-1。
思路:
假设要进行p次正确提交,总共q次提交,q-p次非正确提交, (a+p)/(b+q) = nc/nd , 其中 0<=p<=q n>=1 且都是整数
所以 p = nc-a, q = nd-b p、q都是n的递增函数,所以题意要我们求出最小的q,因为a+p=nc,b+q=nd,所以q越小意味着n越小, 所以二分n寻找最小的n满足条件,无满足输出-1
代码:
LL l = 1, r = 1e9;
LL ans = -1;
while(l<=r)
{
LL mid = (l+r)/2;
LL p = mid*c-a, q = mid*d-b;
if(p>=0 && q>=0 && p<=q)
{
r = mid-1;
ans = q;
}
else
l = mid+1;
}
cout << ans << endl;
从这道题可以看出二分的作用,以后还是要加强多做题,常话说熟能生巧,题目看多了做多了自然会形成一种条件反射。
三.
double精度有限,为了解决这个问题,我们可以设置一个eps=1e-8判断两个数是否完全接近
四.
总结:最近感觉前段学的算法学的时候很皮毛,不扎实,现在没有巩固都忘得差不多啦,而且最近做题也很少,要重新调整一下状态,cf上的很多题都很好,可以按由简到难得方式先做一些思维题提高代码的实现能力,很难的算法先放放,等自己足够熟练啦再统一训练。还有注意:1.提高自己的代码实现能力,不能眼高手低,总觉得大概是那个意思,都要自己亲手打一遍才能真正熟练。2.要养成自己独立做题的习惯,可能以前的老毛病 ,一遇到不会的题时,第一个想到的就是题解,看了人家的思路之后感叹“对,就是这样”,感觉人家的思路自己都会,但其实不然,一道题为什么会想到那个思路,这个问题的转化过程很重要,否则进步实在是太小啦,感觉自己也做了题,但其实都没有转化为自己能信手拈来的东西。好吧,主要就是这些问题啦,以后一定要改正。