做题感悟:在搜二分题时搜到它,不小心看到一个标题(二分+排序),以后不能这样找题目做了,知道方法就没意思了,其实这题很水。
解题思路:( 1 ).可以二分 + 排序(去重,也可以不去重),因为没去重错了几次 ; ( 2 ). map 可以轻松解决(时间比较长)。
代码(二分+排序):
#include<stdio.h>
#include<algorithm>
using namespace std ;
int g[100005],g1[100005] ;
int binary_search(int x,int y,int n) // 二分
{
int mid ;
while(x<y)
{
mid=x+(y-x)/2 ;
if(g1[mid]==n)
return mid ;
else
g1[mid] > n ? y=mid : x=mid+1 ;
}
return -1 ;
}
int main()
{
int T,i,k,n ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d%d",&n,&k) ;
for(i=0 ;i<n ;i++)
scanf("%d",&g[i]) ;
sort(g,g+n) ;
int r=1 ; g1[0]=g[0] ;
for(i=1 ;i<n ;i++) // 去重
if(g[i]!=g[i-1])
g1[r++]=g[i] ;
int num=0 ;
for(i=0 ;i<r ;i++)
{
int a=k-g1[i] ;
if(a<g1[i]) continue ;
if(g1[i]*2==k)
{
num++ ;continue ;
}
int mx=binary_search(0,r,a) ;
if(mx!=-1)
num+=2 ;
}
printf("%d\n",num) ;
}
return 0 ;
}
代码(map):
#include<stdio.h>
#include<algorithm>
#include<map>
using namespace std ;
map<int,int>m ;
int g[100005] ;
int main()
{
int T,n,k ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d%d",&n,&k) ;
m.clear() ; // 一定要清空
int r=0,x ;
for(int i=0 ;i<n ;i++)
{
scanf("%d",&x) ;
if(!m[x])
{
g[r++]=x ; m[x]=1 ;
}
}
int num=0 ;
for(int i=0 ;i<r ;i++)
{
if(m[k-g[i]]&&k>=g[i])
num+=1 ;
}
printf("%d\n",num) ;
}
return 0 ;
}