题目链接:http://poj.org/problem?id=2356
Description
Input
Output
Sample Input
5 1 2 3 4 1
Sample Output
2 2 3
【题目大意】
首先输入一个n,然后给你n个数,让你从中找到 m个数, 1<=m<=n,使得这m个数的和是n的倍数;如果找不到输出0;
【分析】
我们先用一个sum数组,将a【0】, a【0】+a【1】,a【0】+a【1】+a【2】......储存起来;
然后判断这些数能否整除n,如果能则输出下标,然后直接从第一个数开始依次输出即可(题目是special judge,只要找到即可,而且顺序也是in arbitrary order.)
然后,关键的地方来了,因为sum[I]%n一定是属于【1~n-1】的,而sum总共有n个,根据鸽巢定理
把多于n个的物体放到n个抽屉里,则至少有一个抽屉里有2个或2个以上的物体。
所以n个 sum【i】%n中,至少有两个是一样的;(因此,此题一定有解,不存在输出0的情况)
如果我们找到,则说明(sum[j]-sum[i])%n==0 (假设一个是sum【i】,一个是sum【j】,j>i,)
也就是 加在 i j 之间的数的和是 n的倍数,只要依次将他们输出就可以了。
【代码如下】
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn = 10010; int num[maxn]; int mod[maxn]; int sum[maxn]; int main() { int n; cin>>n; memset(mod, -1 ,sizeof(mod)); for(int i=0;i<n;i++) { cin>>num[i]; if(i>0) sum[i]=sum[i-1]+num[i]; else sum[i]=num[i]; } int sign=0; for(int i=0;i<n;i++) { if(sum[i]%n==0) { sign=1; cout<<i+1<<endl; for(int j=0;j<=i;j++) cout<<num[j]<<endl; break; } if(mod[sum[i]%n]!=-1)//如果被赋值过了,则说明遇到相同的余数了; { int tm=i-mod[sum[i]%n]; cout<<tm<<endl; for(int j=mod[sum[i]%n]+1;j<=i;j++) cout<<num[j]<<endl; break; } mod[sum[i]%n]=i;//将取余的数保存起来 } return 0; }也是参考了,博主的代码和思路 大神博客 ,代码中值得注意的技巧是用mod数组来储存余数。