51Nod - 1103 N的倍数 抽屉定理

本文介绍如何利用抽屉原理解决一类数列问题:从给定的长度为n的正整数序列中找到若干个数,使得这些数的和是n的倍数。文章详细解释了抽屉原理的应用,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接




思路:


这个题是一个抽屉定理的典型应用.当看到n个数模n的时候,还要确定某种关系,就可以试试抽屉定理.

抽屉原理的一种更一般的表述为: “把多于kn个东西任意分放进n个空抽屉(k是正整数),那么一定有一个抽屉中放进了至少k+1个东西。” 


对于这个题目,首先很简单的是我们知道:如果有几个数加起来%n==0,那么这几个数的和就一定是N的倍数了.

那么找不到%n为0的数怎么办呢,一个数%n 可能产生n中结果,去掉=0的,就剩下了n-1种结果,对于一个长度为n的数列,

我们维护其前缀和,因为都是正数,所以一定会产生n个结果,那么%n之后根据抽屉原理,肯定有两个是相同的,那么这两个

结果相同的数的中间的数,就一定满足条件了.输出即可.

题目中还说有找不到的情况,我没有考虑,因为一定按照我们说的一定会找到,不存在找不到的情况,


#include<bits/stdc++.h>
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define exp 0.00000001
#define  pii  pair<int, int>
#define  mp   make_pair
#define  pb   push_back
using namespace std;
typedef long long ll;
const int maxn=5e4+10;
int n; 
int sum[maxn];
int a[maxn];
int main()
{
	Ri(n);
	int item=0;
	for(int i=1;i<=n;i++)
	{
		Ri(a[i]);
		sum[i]=(sum[i-1]+a[i])%n;
		if(sum[i]==0)
		{
			item=i;
		}
	}
	if(item)
	{
		Pi(item);
		for(int i=1;i<=item;i++)
		Pi(a[i]);
	}
	else
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				if(sum[i]==sum[j])
				{
					Pi(j-i);
					for(int ii=i+1;ii<=j;ii++)
					Pi(a[ii]);
					return 0;
				}
			}
		}
	}
 return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Marcus-Bao

万水千山总是情,只给五角行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值