noj大作业c语言扫雷源代码,电信学院第一届新生程序设计竞赛题解及std

样例中符合条件的5种组合如下:

{-45 -27 42 30}

{26 30 -10 -46}

{-32 22 56 -46}

{-32 30 -75 77}

{-32 -54 56 30}

a+b+c+d=0,(a+b)=-(c+d) ,

就是预处理出a+b和c+d,然后二分找-(c+d)

(二分或者用stl的hash unordered_map优化,打开C++11用这个

#include

using namespace std;

typedef long long ll;

const int N=;

ll a[N],b[N];

unordered_map ma;

int main()

{

int n,i,j;

scanf("%d",&n);

for(i=;i

for(i=;i

for(i=;i

for(j=;j

++ma[a[i]+b[j]];

for(i=;i

for(i=;i

ll ans=;

for(i=;i

for(j=;j

ans+=ma[-a[i]-b[j]];

printf("%lld\n",ans);

return ;

}

出题人的代码

#include

#include

#include

using namespace std;

#define MAX 4005

int a[MAX],b[MAX],c[MAX],d[MAX];

int cd[MAX*MAX];

int main()

{

//freopen("test.in","r",stdin);

//freopen("test.out","w",stdout);

int n,i,j;

cin>>n;

for(i=;i

for(i=;i

for(i=;i

for(i=;i

for(i=;i

for(j=;j

cd[n*i+j]=c[i]+d[j];

sort(cd,cd+n*n);

long long res=;

for(i=;i

for(j=;j

{

int s=-a[i]-b[j];

res+=upper_bound(cd,cd+n*n,s)-lower_bound(cd,cd+n*n,s);

}

cout<

return ;

}

对着库函数的二分实现一下,库函数的二分实现

#include

using namespace std;

const int m=;

int n,a[m],b[m],c[m],d[m],cd[m*m];

int low(int key)

{

int step,mid,L=,R=n*n;

while(R>)

{

step=R>>,mid=L+step;

key>cd[mid]?(L=mid+,R=R-step-):(R=step);

}

return L;

}

int up(int key)

{

int step,mid,L=,R=n*n;

while(R>)

{

step=R>>,mid=L+step;

key>=cd[mid]?(L=mid+,R=R-step-):(R=step);

}

return L;

}

int main()

{

int i,j;

long long sum=;

scanf("%d",&n);

for(i=; i

scanf("%d",&a[i]);

for(i=; i

scanf("%d",&b[i]);

for(i=; i

scanf("%d",&c[i]);

for(i=; i

scanf("%d",&d[i]);

for(i=; i

for(j=; j

cd[i*n+j]=c[i]+d[j];

sort(cd,cd+n*n);

for(i=; i

for(j=; j

{

int s=-a[i]-b[j];

sum+=up(s)-low(s);

}

cout<

return ;

}

没学会二分的这里看

#include

#include

#define m 4005

int n,a[m],b[m],c[m],d[m],cd[m*m];

int low(int t)

{

int l=,r=n*n;

while(l

{

int mi=l+(r-l)/;

if(cd[mi]

else r=mi;

}

return l;

}

int up(int t)

{

int l=,r=n*n;

while(l

{

int mi=l+(r-l)/;

if(cd[mi]<=t)l=mi+;

else r=mi;

}

return l;

}

int main()

{

int i,j;

long long sum=;

scanf("%d",&n);

for(i=; i

scanf("%d",&a[i]);

for(i=; i

scanf("%d",&b[i]);

for(i=; i

scanf("%d",&c[i]);

for(i=; i

scanf("%d",&d[i]);

for(i=; i

for(j=; j

cd[i*n+j]=c[i]+d[j];

std::sort(cd,cd+n*n);

for(i=; i

for(j=; j

{

int s=-a[i]-b[j];

sum+=up(s)-low(s);

}

printf("%I64d",sum);

return ;

}

简单的实现,有点慢

利用绝对值很小去hash,solution from zhouzexi

#include

using namespace std;

unordered_mapmp[],mo;

int main(){

ios::sync_with_stdio(false);

cin.tie();

cout.tie();

int n,x;

int T=;

cin>>n;

while(T--)

for(int i=;i

cin>>x;

mp[T][x]++;

}

unordered_map::iterator it,it2;

for(it=mp[].begin();it!=mp[].end();it++)

for(it2=mp[].begin();it2!=mp[].end();it2++)

mo[it->first+it2->first]+=it->second*it2->second;

__int64 s=;

for(it=mp[].begin();it!=mp[].end();it++)

for(it2=mp[].begin();it2!=mp[].end();it2++)

s+=1LL*mo[-(it->first+it2->first)]*it->second*it2->second;

cout<

}

数组的hash,可以0ms

#include

using namespace std;

int ans[], M[][];

int main()

{

//freopen("test.in","r",stdin);

ios::sync_with_stdio(false), cin.tie(), cout.tie();

int n;

cin >> n;

int ma = , mi = ;

for (int j = ; j < ; j++)

for (int i = , x; i < n; i++)

{

cin >> x;

x = x + ;

ma = max(ma, x);

mi = min(mi, x);

M[j][x]++;

}

for (int i = mi; i <= ma; i++)

for (int j = mi; j <= ma; j++)

ans[i + j] += M[][i] * M[][j];

long long s = ;

for (int i = mi; i <= ma; i++)

for (int j = mi; j <= ma; j++)

s += 1LL * ans[ - (i + j)] * (M[][i] * M[][j]);

cout << s << endl;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值