poj 2356 Find a multiple(鸽巢原理+标记)
2015-08-03 08:53
204 查看
题目:http://poj.org/problem?id=2356
大意:给出n个数字,在其中找出连续的数字使其和是n的倍数,不能找到输出0。
设sum[i]=a1+a2+……+ai,n个sum[i]模n的结果范围是[0,n-1]。由鸽巢原理可知:必有一个sum[i]的模结果是0或有两个sum[i]模结果相等(也就是sum[j]-sum[i]=0)。所以一定存在着这样连续数字的和是n的倍数。N<=1e4,如果用纯暴力可能有超时的风险,以空间换时间,根据“必有一个sum[i]的模结果是0或有两个sum[i]模结果相等”使用标记法。
大意:给出n个数字,在其中找出连续的数字使其和是n的倍数,不能找到输出0。
设sum[i]=a1+a2+……+ai,n个sum[i]模n的结果范围是[0,n-1]。由鸽巢原理可知:必有一个sum[i]的模结果是0或有两个sum[i]模结果相等(也就是sum[j]-sum[i]=0)。所以一定存在着这样连续数字的和是n的倍数。N<=1e4,如果用纯暴力可能有超时的风险,以空间换时间,根据“必有一个sum[i]的模结果是0或有两个sum[i]模结果相等”使用标记法。
#include <iostream> #include <cstdio> #include<cstring> using namespace std; const int maxn=1e4+5; int sum[maxn],tag[maxn],a[maxn],l,r,N; int main() { //freopen("cin.txt","r",stdin); while(cin>>N){ memset(sum,0,sizeof(sum)); memset(tag,-1,sizeof(tag)); tag[0]=0; for(int i=1;i<=N;i++){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; int m=sum[i]%N; if(tag[m]==-1) tag[m]=i; else { l=tag[m]; r=i; } } printf("%d\n",r-l); for(int i=l+1;i<=r;i++){ printf("%d\n",a[i]); } } return 0; }
相关文章推荐
- 【转】java虚拟机参数详解之-Xms/-Xmx,运行时内存分配多少
- ./bin/spark-shell 报错:java.net.UnknownHostException
- Knockout应用开发指南
- Scikit Learn: 在python中机器学习
- Android 基础控件之进度条ProgressBar的实现
- JavaScript权威指南_146_第15章_脚本化文档_15.10-其他文档特性-Document的属性
- 取得viewController展示view
- 处理图片被渲染的效果
- UI 03 UITextField
- 权限管理(二)
- Knockout应用开发指南
- HDU 1864 最大报销额(01背包)
- kafka初步
- uva 11552
- [高可用]Ubuntu下Haproxy + Keepalived 实现SuperMap iServer高可用负载均衡实现(2)
- 一句话的设计模式(收藏)
- Linux下常用的文件操作技巧汇编:创建、复制、移动与删除
- java常见的几种异常
- AHoi 行星序列
- 提高Android Studio中Gradle执行效率