POJ-2356 Find a multiple(鸽巢原理)题目数据太垃圾了!!

本文介绍了一种算法,用于从一组数字中找到若干个数的和为特定整数倍的组合。利用离散数学中的鸽巢原理,通过记录部分和的余数来确定符合条件的数字序列。

题意:在给出的N个数字中找出M个数字和为N的整数倍


思路:在离散数学中鸽巢原理大概意思是,有N+1个数字放在N个盒子里必定有一个盒子有2个或者2个以上个数字..

本题如果sum[I] %n==0,那么这组数字就满足条件,如果没有一组数字是满足条件的,那么我们考虑多个数字的组合

如果前i个数字和 与前j个数字和%n相等, 那么 第i+1~j个数字的和必定是n的k倍

先给个AC的,思路正确的代码。

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
int n,m;
using namespace std;
int a[15001];
int sum[15001];
int save[10005];
int main()
{
    int n;
    cin>>n;
    int num=0,ans=0,yes=0,l,r;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        if(!yes)
        {

            sum[i]=(sum[i-1]+a[i]%n)%n;
            if(sum[i]==0)
            {
                l=1;
                r=i;
                ans=r-l+1;
                yes=1;
            }
            if(save[ sum[i] ] )
            {
                l=save[sum[i]]+1;
                r=i;
                yes=1;
                ans=r-l+1;
            }
            save[sum[i]]=i;
        }
    }
    cout<<ans<<endl;
    for(int i=l;i<=r;i++)
        cout<<a[i]<<endl;
}
/*
2
1 1
*/




心疼自己写的代码。竟然AC了。然而自己造的数据都过不去。亏我想证明自己的思路的正确性。。。抓狂垃圾数据!!!!以后想明白如何正确这个东西错误再删。。。

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
int n,m;
using namespace std;
int a[15001];
int sum[15001];
int save[10005];
int main()
{
    int n;
    cin>>n;
    int num=0,ans=0,yes=0;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        if(!yes)
        {
            if(a[i]%n==0)
            {
                ans=1;
                yes=i;
                num=i;
            }
            sum[i]=(sum[i-1]+a[i])%n;
            if( save[ n-a[i]%n ])
            {
                yes=i;
                num=save[n- a[i]%n ];
                ans=1+save[n-a[i]%n];
            }
            save[ sum[i]%n ]=i;
        }
    }
    cout<<ans<<endl;
    for(int i=1;i<=num;i++)
        cout<<a[i]<<endl;
    if(ans!=1)
        cout<<a[yes]<<endl;
}
5
2 4 1 1 1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值