最近练的都是二分【虽然有的题目用别的神奇的东西A了】,以后会更新的吧…
链接1♂
查找最接近的元素
总时间限制: 1000ms 内存限制: 65536kB
描述
在一个非降序列中,查找与给定值最接近的元素。
输入
第一行包含一个整数n,为非降序列长度。1 <= n <= 100000。
第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000,000之间。
第三行包含一个整数m,为要询问的给定值个数。1 <= m <= 10000。
接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000,000之间。
输出
m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
样例输入
3
2 5 8
2
10
5
样例输出
8
5
这还是暑假做的,现在差不多都忘了
当时都用的while循环水,然而我还naive的用递归…
没啥好解释的吧【虽然很蠢的调了很久…
果然代码能力太弱啊…
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL a[100000+50];
LL n;
LL binary_search(LL left,LL right,LL e)
{
LL mid=(left+right)>>1;
if(left>=1&&right<=n)
{
if(a[mid]==e)
return e;
else if(left==right&&a[mid]!=e)
{
if(a[left]-e>=e-a[left-1])
return a[left-1];
return a[left];
}
else if(a[mid]<e)
return binary_search(mid+1,right,e);
else if(a[mid]>e)
return binary_search(left,mid,e);
}
}
int main()
{
scanf("%lld",&n);
for(LL i=1;i<=n;i++)
scanf("%lld",&a[i]);
LL m,x;
scanf("%lld",&m);
while(m--)
{
cin>>x;
if(x<=a[1])
cout<<a[1]<<endl;
else cout<<binary_search(1,n,x)<<endl;
}
return 0;
}
/*
3
2 5 8
2
10
5
*/
和为给定数
总时间限制: 1000ms 内存限制: 65536kB
描述
给出若干个整数,询问其中是否有一对数的和等于给定的数。
输入
共三行:
第一行是整数n(0 < n <= 100,000),表示有n个整数。
第二行是n个整数。整数的范围是在0到10^8之间。
第三行是一个整数m(0 <= m <= 2^30),表示需要得到的和。
输出
若存在和为m的数对,输出两个整数,小的在前,大的在后,中间用单个空格隔开。若有多个数对满足条件,选择数对中较小的数更小的。若找不到符合要求的数对,输出一行No。
样例输入
4
2 5 1 4
6
样例输出
1 5
mdzz…
暑假是用来当set练习做的,最开始WA到不行,后来才发现要用multiset…然后成功水过…
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
multiset<int>S;
multiset<int>::iterator it;
multiset<int>::iterator it2;
int a[100000+50];
bool flag=0;
int main()
{
int n,m;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
S.insert(a[i]);
cin>>m;
for(it=S.begin();it!=S.end();it++)
{
if(*it<=m)
{
it2=S.find(m-*it);
if(it2!=S.end()&&it2!=it)
{
cout<<min(*it,*it2)<<" "<<max(*it,*it2)<<endl;
flag=1;
break;
}
}
}
if(!flag)
puts("No");
return 0;
}
后来又用二分做,第一遍zz把num[mid]写成了mid…结果居然水了70…这数据…
后来重打了一遍,感觉二分边界这东西还是很迷的…后来有WA到不行,才发现忘了判重…【好想发表情来表达我的无语怎么办QAQ
在二分之前不要忘记让序列变得有序…
代码如下(后面带一个自己生成的小数据):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=100000+10;
int num[MAXN];
int main()
{
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
scanf("%d",&m);
sort(num+1,num+n+1);
for(int i=1;i<=n;i++)
{
int l=0,r=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(num[mid]+num[i]<m)
l=mid+1;
else if(num[mid]+num[i]>m)
r=mid-1;
else
{
//puts("haha");
if(mid!=i)
{
printf("%d %d\n",min(num[i],num[mid]),max(num[i],num[mid]));
return 0;
}
else
{
puts("No");
return 0;
}
}
}
}
puts("No");
return 0;
}
/*
5
3 0 1 2 5
5
26
96 38 25 79 8 99 71 49 59 26 96 15 87 19 19 29 14 37 41 56 85 14 2 52 46 50
23
4
2 5 1 4
6
*/
不重复地输出数
总时间限制: 1000ms 内存限制: 65536kB
描述
输入n个数,从小到大将它们输出,重复的数只输出一次。保证不同的数不超过500个。
输入
第一行是一个整数n。1 <= n <= 100000。
之后n行,每行一个整数。整数大小在int范围内。
输出
一行,从小到大不重复地输出这些数,相邻两个数之间用单个空格隔开。
样例输入
5
2 4 4 5 1
样例输出
1 2 4 5
第一眼,set可以水【对,又是set】
真的,STL大发好啊,成功水过…
代码如下:
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
set<int>S;
set<int>::iterator it;
int main()
{
int n,m;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
S.insert(m);
}
for(it=S.begin();it!=S.end();it++)
cout<<*it<<" ";
cout<<endl;
return 0;
}
然后有用桶排水了一波…
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
bool b[62000000+10];
int main()
{
int k,l,n;
cin>>n;
int hah=0;
for(int i=1;i<=n;i++)
{
cin>>k;
hah=max(hah,k);
b[k]=1;
}
for(int i=0;i<=hah;i++)
if(b[i])
cout<<i<<" ";
return 0;
}
然而用二分打了一波,却成功TLE了TAT
感觉这个大水题没人用二分打吧…
还是放一下代码吧,希望各路神犇不要嘲笑蒟蒻啊>_<
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=100000+10;
int num[MAXN];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
sort(num+1,num+1+n);
int mn=num[1],mx=num[n];
num[1]=0;
//cout<<*lower_bound(num+1,num+1+n,1);
int last=0;
while(mn!=mx)
{
if(last!=mn)
printf("%d ",mn);
last=mn;
int j=lower_bound(num+1,num+1+n,mn)-num;
mn=num[j];
num[j]=0;
}
printf("%d\n",mx);
return 0;
}
/*
5
2 4 4 5 1
*/