2223: 鸽巢定理
Time Limit: 1000 ms Memory Limit: 65536 kB
Total Submit : 142 (22 users) Accepted Submit : 11 (9 users) Page View : 339
小明最近在学习鸽巢定理,鸽巢定理又被叫做抽屉原理或鞋盒原理,它的一种最简单形式如下:
如果n + 1个物体被放进n个盒子,那么至少有一个盒子包含两个或更多的物体。
他对这个定理非常感兴趣,于是看了大量的例子和习题,诸如”在13个人中存在两个人,他们的生日在同一个月份里”,”在整数1,2,…,200中我们选择101个整数,存在两个这样的整数,使得其中一个能被另一个整除”等等。今天,他遇到了一个更难的习题:
对任意给定的52个整数,存在其中的两个整数,要么两者的和能被100整除,要么两者的差能被100整除。
小明挠着头想了一想,似乎也不难证明。证明完这题以后,小明想到了一个进阶版的问题:
给定长度为N的数列{Ai}, i = 1,2,3..N, 存在多少对组合(i, j) (i < j),使得要么Ai与Aj的和能被M整除,要么Ai与Aj的差能被M整除。
对于这个问题,小明就束手无策了。所以,是时候到你这位编程高手上场了。
如果n + 1个物体被放进n个盒子,那么至少有一个盒子包含两个或更多的物体。
他对这个定理非常感兴趣,于是看了大量的例子和习题,诸如”在13个人中存在两个人,他们的生日在同一个月份里”,”在整数1,2,…,200中我们选择101个整数,存在两个这样的整数,使得其中一个能被另一个整除”等等。今天,他遇到了一个更难的习题:
对任意给定的52个整数,存在其中的两个整数,要么两者的和能被100整除,要么两者的差能被100整除。
小明挠着头想了一想,似乎也不难证明。证明完这题以后,小明想到了一个进阶版的问题:
给定长度为N的数列{Ai}, i = 1,2,3..N, 存在多少对组合(i, j) (i < j),使得要么Ai与Aj的和能被M整除,要么Ai与Aj的差能被M整除。
对于这个问题,小明就束手无策了。所以,是时候到你这位编程高手上场了。
Input
输入为多组数据。
每组数据第一行两个整数N, M, 接下来N行每行一个整数,表示Ai。(1 <= N <= 100000, 1 <= M <= 10000, 1 <= Ai <= 10^9)
每组数据第一行两个整数N, M, 接下来N行每行一个整数,表示Ai。(1 <= N <= 100000, 1 <= M <= 10000, 1 <= Ai <= 10^9)
Output
每组数据输出一行,为一个整数,代表有多少对组合满足题目的条件。
Sample Input
3 2 1 2 4
Sample Output
1
Hint
样例中满足条件的组合只有(2, 3)。如果不清楚如何处理多组输入,请参照1001题。
Source
Best User : qq616590927
hash即可,注意数的范围
#include<iostream>
using namespace std;
#define MAX 10000+10
int hash[MAX];
int main()
{
int n,m,i,j,temp;
double ans;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(hash,0,sizeof(hash));
for(i=0;i<n;i++)
{
cin>>temp;
hash[temp%m]++;
}
ans=0;
for(i=0;i<m;i++)
{
if(hash[i]>1)
ans+=((double)hash[i]*(hash[i]-1))/2;不能将超界的int型直接赋值给double可能得到错的结果
if(i!=m-i&&i<=m/2)
ans+=((double)hash[i]*hash[m-i]);
}
//cout<<ans<<endl;
printf("%.0lf\n",ans);
}
return 0;
}