给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例 1:
输入: [1,3,4,2,2]
输出: 2
示例 2:
输入: [3,1,3,4,2]
输出: 3
说明:
不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O(n^2) 。
数组中只有一个重复的数字,但它可能不止重复出现一次。
比较典型的二分查找,但是需要注意右区间ri=mid,而不是ri=mid-1
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n=nums.size();
int le=1,ri=n-1;
while(le<ri)
{
int mid=(le+ri)/2;
int cnt=0,l=0,r=0;
for(int i=0;i<n;i++)
{
if(nums[i]<=mid) cnt++;
}
if(cnt<=mid) le=mid+1;
else ri=mid;
}
return le;
}
};
Problem Description
Now, here is a fuction:
F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)
Can you find the minimum value when x is between 0 and 100.
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)
Output
Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.
Sample Input
2
100
200
Sample Output
-74.4291
-178.8534
求函数的最小值,先求单调性,只有两种情况:先减后增,一直减.求出fx的导函数f'(x),二分找到f'(x)=0的点即是最小值点.二分的时候需要注意是double型
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
double eps=1e-5;
double y;
double Fx(double x){
return 6.0*x*x*x*x*x*x*x+8.0*x*x*x*x*x*x+7.0*x*x*x+5.0*x*x-y*x;
}
double fx(double x){
return 42.0*x*x*x*x*x*x+48.0*x*x*x*x*x+21.0*x*x+10.0*x-y;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%lf",&y);
double l=0.0,r=100.0;
double ans=Fx(100.0);
while(r-l>eps){
double mid=(l+r)/2.0;
double now=fx(mid);
ans=min(ans,Fx(mid));
if(now==0){
break;
}
else if(now>0)
r=mid;
else l=mid;
}
printf("%.4f\n",ans);
}
}
并查集-nowcoder 加边的无向图
给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~
输入描述:
第一行两个正整数 n 和 m 。
接下来的m行中,每行两个正整数 i 、 j ,表示点i与点j之间有一条无向道路。
输出描述:
输出一个整数,表示答案
示例1
输入
4 2
1 2
3 4
输出
1
备注:
对于100%的数据,有n,m<=100000。
虽然只是一道模板题,但是不能仅仅只是为了A题,还有优化,使用路径压缩带来的时间上的节省不是一点点!!!
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,m,fa[maxn];
void init(){
for(int i=1;i<=n;i++) fa[i]=i;
}
int find_root(int x){
int temp,now=x;
while(x!=fa[x]) x=fa[x];
while(now!=x){
temp=fa[now];
fa[now]=x;
now=temp;
}
return x;
}
void union_both(int u,int v){
int root_u=find_root(u);
int root_v=find_root(v);
if(root_u!=root_v) fa[root_u]=root_v;
}
int main()
{
int u,v;
scanf("%d%d",&n,&m);
init();
while(m--){
scanf("%d%d",&u,&v);
union_both(u,v);
}
int ans=0;
for(int i=1;i<=n;i++) if(fa[i]==i) ans++;
printf("%d\n",ans-1);
}