今天学到的新知识集合
1.bool函数可以直接对变量进行操作而且返回值为0.1;
如下面这个代码就可以看到没有输入a[i]的形参但是仍然可以对其进行操作
return 后面的语句为真就返回1
否则返回0
所以用于if(judge(k))判断是可以的
bool judge(const int &len) // 用于判断的 子函数 { long long cnt=0; //部分情况可能爆int for (int i=0;i<n;i++) cnt+= (long long)(a[i]/len); return cnt>=k; }
2.关于二分法
二分法的最简单形式就是区间的取换
目前我觉得难点在于判断条件
今天做了几道二分题
感觉自己是个菜鸡
第一题就是练手的模板题
用于弄清楚二分法的概念
#include <iostream> #include<bits/stdc++.h> using namespace std; int n,x,i,mid,t,w; const int N=2000005; int a[N]; int main() { while(~scanf("%d %d",&n,&x)) { for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); t=0;w=n-1; while(t<=w) { mid=(t+w)/2; if(a[mid]==x) break; else if(a[mid]>x) w=mid-1; else if(a[mid]<x) t=mid+1; } if(a[mid]==x) printf("%d\n",mid+1); else printf("%d\n",mid); } //cout << "Hello world!" << endl; return 0; }
写完这题之后就可以直接用c艹内置的取下标函数了
#include <iostream> #include<bits/stdc++.h> using namespace std; const int N=2000006; int a[N]; int n,x; int t,w,mid; int main() { while(~scanf("%d%d",&n,&x)) { for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); printf("%d\n",upper_bound(a,a+n,x)-a); } //cout << "Hello world!" << endl; return 0; }
然后就是神奇的桶排序,居然出现在了二分的题了= =
(超时问题一直是心里不可言说的痛苦
小清新又要使坏了,他发现二倍问题(Problem 8)并不能难住大家,于是他决定悄咪咪的改一波数据。
于是:
给定2到10,000个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍。比如给定1 4 3 2 9 7 18 22,得到的答案是3,因为2是1的两倍,4是2个两倍,18是9的两倍。
Input
输入包括n组测试数据。第一行一个正整数 n 。
接下来n行表示n组数据,每组数据为一行,给出2到10,000个两两不同且小于100,000的正整数。每一行最后一个数是0,表示这一行的结束后,这个数不属于那2到10,000个给定的正整数。
Output
对每组输入数据,输出一行,给出有多少个数对满足其中一个数是另一个数的两倍。
Sample Input
3
1 4 3 2 9 7 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0
Sample Output
3 2 0
对于这道题我的感想就是删多组删多组= =;
#include <iostream> #include<bits/stdc++.h> using namespace std; int n; const int N=10002; const int K=2000005; int a[N],pai[K]; int i,j,temp,ans,zu,k; int main() { scanf("%d",&zu); for(i=0;i<zu;i++) { k=0;ans=0; memset(pai,0,sizeof(pai)); while(scanf("%d",&temp)&&temp) { a[++k]=temp; pai[temp]++;; } for(j=1;j<=k;j++) { if(pai[2*a[j]]!=0) ans++; } printf("%d\n",ans); } //cout << "Hello world!" << endl; return 0; }
后面的题我都觉得难= =
好难
思路都有就是都RE
憋屈
烦到写不下去了
先随便粘代码后面补上
#include <bits/stdc++.h> using namespace std; const double pi=acos(-1.0); int h; int check(double r) { if (pow(r,pi)>=h*(pi*r*r-r)) return 1; else return 0; } int main() { //ios::sync_with_stdio(false); int t; double l,r,mid; scanf("%d",&t); while(t--) { scanf("%d",&h); l=0;r=100000; while(l<r) { mid=(l+r)/2.0; if (r-l<=1e-8) break; if (check(mid)==1) //mid大了 r=mid; else l=mid; } printf("%.4lf\n",mid); } return 0; }
#include <iostream> #include<bits/stdc++.h> #include<math.h> const double pai=acos(-1.0); int zu,h; double v1,v2; double r; double temp,i,j,mid,t; using namespace std; int judge(double r) { if (pow(r,pai)>=h*(pai*r*r-r)) return 1; else return 0; } int main() { scanf("%d",&zu); while(zu--) { scanf("%d",&h); t=0;r=100000; while(t<r) { mid=(t+r)/2; if(r-t<=1e-8) break; if(judge(mid)) r=mid; else t=mid; } printf("%.4f\n",r); } //cout << "Hello world!" << endl; return 0; }
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define double long long int using namespace std; const int maxn=1e5+10; int n,k; double a[maxn]; bool check(double x) { int cnt=0; for(int i=0;i<n;i++) cnt+=(int)(a[i]/x); return cnt>=k; } int main() { scanf("%d%d",&n,&k); for(int i=0;i<n;i++) scanf("%lf",&a[i]); double eps=1e-6; double l=0.0,r=0x3f3f3f3f; while(r-l>eps) { double mid=l+(r-l)/2.0; if(!check(mid)) r=mid; else l=mid+eps; } printf("%lld\n",(floor(r*100)/100.0)); return 0; }