抽屉定理poj 3370|| hdu1808 Halloween treats || hdu 1205 吃糖果 ||poj 2356
2015-07-29 17:42
453 查看
hdu 1808 || poj 3370原题链接:点击打开链接
思路(转):
首先简单说一下鸽巢原理,就是有n+1个球,放在n个盒子中,那么至少有一个盒子有两个或更多的球。
而这两道题正是运用了这个思想。先对数列求前N项和,有s1=a1,s2=a1+a2,
s3=a1+a2+a3,......,sn=a1+a2+a3+...+an。若其中有和可以整除m,那么即可得出答案,否则,所得的余数只会是1,2,...,n-1,因此,必存在至少两个数模除m后有相同余数r,即si=b*m+r,sj=c*m+r,则si-sj=(b-c)*m。则序列ai到aj的和即为所求。
code:
hdu 1205:
原题链接:点击打开链接
思路:找出数量最多的某类糖果(m个),剩下sum-m个,则能产生(sum-m+1)个位置来放置数量最多的糖果
如果m>(sum-m+1)则说明不能将数量最多的吃完,反过来看,m个数量最多的某类糖果,相当于有m块挡板,产生了m+1个空格可以用来放置其余的糖果,这些数量不太多的糖果 也可以看做是将之前产生的挡板的厚度增加的。
比如 :m1x1n1 m2n2 m3n3
m4n4 m5n5;
其中 x1就相当于将前一个挡板加厚了 只要能保证数量最多的糖果被吃完 就能被吃完
code:
poj 2356:与poj3370 一样 除了输出之外。
code:
思路(转):
首先简单说一下鸽巢原理,就是有n+1个球,放在n个盒子中,那么至少有一个盒子有两个或更多的球。
而这两道题正是运用了这个思想。先对数列求前N项和,有s1=a1,s2=a1+a2,
s3=a1+a2+a3,......,sn=a1+a2+a3+...+an。若其中有和可以整除m,那么即可得出答案,否则,所得的余数只会是1,2,...,n-1,因此,必存在至少两个数模除m后有相同余数r,即si=b*m+r,sj=c*m+r,则si-sj=(b-c)*m。则序列ai到aj的和即为所求。
code:
#include<stdio.h> #include<string.h> int yushu[100010],d[100010]; int main() { int m,i,j,ans,c,n,sum; while(scanf("%d%d",&c,&n)!=EOF) { if(c==0&&n==0) break; memset(yushu,0,sizeof(yushu)); for(i=1;i<=n;i++) scanf("%d",&d[i]); int st,ed; sum=0; for(i=1;i<=n;i++) { sum=(sum+d[i])%c; if(sum==0) { st=1; ed=i; break; } else if(yushu[sum]) { st=yushu[sum]+1; ed=i; break; } else yushu[sum]=i; } for(i=st;i<=ed;i++) printf(i==ed?"%d\n":"%d ",i); } return 0; }
hdu 1205:
原题链接:点击打开链接
思路:找出数量最多的某类糖果(m个),剩下sum-m个,则能产生(sum-m+1)个位置来放置数量最多的糖果
如果m>(sum-m+1)则说明不能将数量最多的吃完,反过来看,m个数量最多的某类糖果,相当于有m块挡板,产生了m+1个空格可以用来放置其余的糖果,这些数量不太多的糖果 也可以看做是将之前产生的挡板的厚度增加的。
比如 :m1x1n1 m2n2 m3n3
m4n4 m5n5;
其中 x1就相当于将前一个挡板加厚了 只要能保证数量最多的糖果被吃完 就能被吃完
code:
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> using namespace std; int main() { int cas; scanf("%d",&cas); __int64 n,maxx,sum,i,t; while(cas--) { sum=0; maxx=-1; scanf("%I64d",&n); for(i=0;i<n;i++) { scanf("%I64d",&t); sum+=t; maxx=max(maxx,t); } if(maxx>(sum-maxx+1)) printf("No\n"); else printf("Yes\n"); } return 0; }
poj 2356:与poj3370 一样 除了输出之外。
code:
#include<stdio.h> #include<string.h> int d[10010],yushu[10010]; int main() { int i,sum=0,st,ed,n; while(scanf("%d",&n)!=EOF) { memset(yushu,0,sizeof(yushu)); for(i =1 ;i<=n;i++) scanf("%d",&d[i]); for(i=1;i<=n;i++) { sum=(sum+d[i])%n; if(sum==0) { st=1; ed=i; break; } else if(yushu[sum]) { st=yushu[sum]+1; ed=i; break; } else yushu[sum]=i; } printf("%d\n",ed-st+1); for(i=st;i<=ed;i++) printf("%d\n",d[i]); } return 0; }
相关文章推荐
- Android打包失败Proguard returned with error code 1. See console
- memcache
- vector之reserve函数
- 防止CSRF跨域攻击
- socket编程——一个简单的例子
- 后台管理,给列表页新增查询功能,所遇到的问题及感想
- 几个简单的html+css+js题目
- shell命令行快速编辑命令
- $.post
- memcache
- Window下memcached安装与测试步骤
- E2202 Required package 'VclJPG' not found
- Android学习之路
- oracle数据类型(3)
- createjs初学-所有的显示对象介绍(2)
- 根据文字算出文字所占区域大小(用于创建多个UILabel时可以用)(不知道这个方法的天猫程序员自从看到这个方法已经哭晕在厕所)
- 欢迎使用CSDN-markdown编辑器
- Contribute/Submit A QEMU Patch
- iOS开发——动画编程OC篇&(一)基本动画
- 解决git版本冲突不能push