POJ 2356 Find a multiple (抽屉原理)

10 篇文章 0 订阅

Find a multiple
Time Limit: 1000MS

Memory Limit: 65536K
Total Submissions: 7597

Accepted: 3311

Special Judge

Description

The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000. This numbers are not necessarily different (so it may happen that two or more of them will be equal). Your task is to choose a few of given numbers ( 1 <= few <= N ) so that the sum of chosen numbers is multiple for N (i.e. N * k = (sum of chosen numbers) for some natural number k).

Input

The first line of the input contains the single number N. Each of next N lines contains one number from the given set.

Output

In case your program decides that the target set of numbers can not be found it should print to the output the single number 0. Otherwise it should print the number of the chosen numbers in the first line followed by the chosen numbers themselves (on a separate line each) in arbitrary order.

If there are more than one set of numbers with required properties you should print to the output only one (preferably your favorite) of them.

Sample Input

5
1
2
3
4
1

Sample Output

2
2
3


题目大意:给n个整数,让你判断这些数中是否存在若干个数的和是n的倍数。

解题思路:这道题是一道比较有趣的数学题,如果直接暴力的做的话据说dfs也是可以过的,不过这里要讲一种更智慧一点的方式,抽屉原理~

        因为一个数模n只有n种可能,所以将这n个整数做前缀和处理,对这n个前缀和模n的情况进行分析,如果其中包含模n等于0的情况,那就直接输出就好,如果不包含的话,由抽屉原理可知,必会存在两个前缀和模n同余,对这两个数作差必然能够整除n,所有只需要将两个前缀和中间的这一段数输出即为答案,通过以上分析我们也可以知道,答案是必然存在的~

AC代码:

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
ll a[10005];
int sum[10005];
int rest[10005];
int main()
{
    memset(rest,0,sizeof(rest));
    int n,i,j;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        sum[i] = sum[i-1] + a[i];
        sum[i] %= n;
        //a[i] %= n;
    }
    for(i=1;i<=n;i++)
    {

        if(sum[i]%n==0)
        {
            cout << i << endl;
            for(j=1;j<=i;j++)
                cout << a[j] << endl;
            break;
        }
        if(rest[sum[i]]==0)//记录下这个余数是否出现过
            rest[sum[i]] = i;
        else
        {
            cout << i-rest[sum[i]] << endl;
            for(j=rest[sum[i]]+1;j<=i;j++)
                cout << a[j] << endl;
            break;
        }
    }
    //cout << "Hello world!" << endl;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值