【题目链接】:http://codeforces.com/contest/577/problem/B

【相似题目】:http://swjtuoj.cn/problem/2383/

【题意】:给出n个数,问是否能从中选出一些数,使得这些数的和是m的倍数。

【题解】:

首先,先明白这样一个事实:

设:sum%dend=rem;

(sum:一些数的和,dend:被除数,rem:余数)

则有:(rem+n)%dend=(sum+n)%dend;

(n为一个新的数)

知道了上面的等式之后,题目就好做了:

设:est[rem]=1 表示存在余数rem,它是通过一些数的和sum%dend得到的。

对于每一个给定的n,

考察 1<=rem<=dend-1 范围内的est[rem],即考察是否存在之前一些数的和sum%dend=rem(不管sum是之前的数是怎么相加得来的)

若存在,即est[rem]=1,则可以通过(rem+n)%dend来求出新的余数,即令est[(rem+n)%dend]=1;

此外,n%dend也是新的余数,即est[n%dend]=1;

若在上面的余数中有一个等于0,即est[0]=1,则说明存在dend的倍数,直接中断循环。

【注意】

在对每一个n的循环中,不能立刻更新est数组,原因是某些情况会导致出错。

出错例子:

设:已有est[1]=1,此时n=1,dend=100;

若令est[(1+n)%dend]=1,即est[2]=1,

则又有est[(2+n)%dend]=1,即est[3]=1,

又有est[(3+n)%dend]=1,即est[4]=1......

最后整个est数组都为1,显然这是错误的。

所以,要一个 i_est 数组来临时更新est数组,最后再更新est数组(详见代码)。

 #include<stdio.h>
int num,dend,t,i,n[];
char est[],i_est[];
int main(){
scanf("%d%d",&num,&dend);
for(t=;t<num;t++){
scanf("%d",&n[t]);
}
for(t=;t<num;t++){
for(i=;i<dend;i++){
if(!est[i]) continue;
i_est[(i+n[t])%dend]=;
}
i_est[n[t]%dend]=;
for(i=;i<dend;i++){
est[i]=i_est[i];
}
if(est[]) break;
}
if(est[]){
printf("YES\n");
}
else{
printf("NO\n");
}
return ;
}

最新文章

  1. [word]用Word2007查找和替换功能批量设置图片位置
  2. 时间控件之赋值问题:datetimebox
  3. 简单的跨平台c/c++日志记录
  4. iOS自定义字体
  5. 源码编译安装screen
  6. jquery中使用event.target的几点
  7. unity, 顶点对齐
  8. jquery上传图片插件plupload
  9. 多线程中lock用法的经典实例
  10. js实现Mac触摸板双指事件(上、下、左、右、放大、缩小)
  11. DirectX 11---从空间变换来看3D场景如何转化到2D屏幕
  12. 支付宝使用流程和踩坑小记(附Demo)
  13. java程序高CPU,如何直接定位(linux系统下命令行操作)
  14. Spring MVC参数封装传递
  15. python --github 刷题
  16. RHEL/CentOS/Fedora各种源
  17. DB2 SQL1477N问题
  18. java web 项目启动的根目录,以及项目启动后使用的端口具体是哪一个
  19. beat冲刺(6/7)
  20. Linux内核设计与实现第八周读书笔记

热门文章

  1. bzoj 4161: Shlw loves matrixI
  2. Hosts文件说明
  3. 记录日志好习惯——Log4net入门(WCF篇)
  4. 关于windowsServer编程
  5. webservice随记
  6. redis的安全问题
  7. Editplus编辑器在php文件中变色显示设置
  8. CentOS 7 禁用IPV6以提高网速
  9. C#启动服务
  10. 并发包同步工具CyclicBarrier