最近練的都是二分【雖然有的題目用別的神奇的東西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
*/