题目链接:http://codeforces.com/problemset/problem/577/B

题目意思:就是给出 n 个数(a1, a2, ..., an) 和 m,问能不能从这 n 个数中选出一些数(不能为空),使得这些数的总和能整除 m 。

  实不相瞒,完全没想法。。。看题解,有个地方看都看不懂: n > m的情况。求助乌冬子,连带被批英语水皮 >___<。还是谢谢他啦,一步一步引导我。

  

  貌似挺多人也有这个疑惑的。他说那个是特例优化,原谅我懒,直接摘抄吧~

  首先要知道一些参数。

  前缀和 Sl  = a1 + a2 + ... + al-1 + al

      Sr = a1 + a2 + ... + al-1 + al + al+1 + ... + ar-1 + ar

      Sr - Sl = al+1 + al+2 + ...ar-1 + ar

  那个翻译就是,如果有两个前缀和 mod m 相等(Sr = Sl(mod m) ),那么就有以下的前缀和向区间和的转化了。

 Sr = Sl (mod m)
==> Sr - Sl = 0 (mod m)
==> a[l+1] + a[l+2] .. + a[r] = 0 (mod m) 
  而到了 n <= m的情况, 之后就是01背包窝~~写不出来,好惨啊= =
  还是用set浅显易懂。。。。
  轮到我用的方法了(都是参考人的,神奇啦)
  *****************************************
  大体思路:保存选的数的各种组合,求出各种和的不同结果,保存在set容器中的 mods 中。当中要用到另一个set :mods_tmp。用来保存当前处理的数a与mods中的各个和,组合出的但在原mods中没有出现的和。一轮迭代之后,将这个mods_tmp添加到mods中。这样不用下次再算嘛~~~~注意,mod m 最多只会出现 m 种结果:0, 1, 2, ..., m-1。所以不用担心超时。
  顺便说说代码中为什么一开始要插入 0,因为可以只选当前输入的那个 a 嘛~~~哈哈哈·~~~
  (1)这个会比(2)快(124ms)

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
using namespace std; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE int n, m;
while (scanf("%d%d", &n, &m) != EOF) { int a, r;
set<int> mods;
set<int> mods_tmp; mods.insert();
for (int i = ; i < n; i++) {
scanf("%d", &a);
for (set<int>::iterator it = mods.begin(); it != mods.end(); ++it) {
int r = (*it + a) % m;
if (r == ) {
printf("YES\n");
return ;
}
mods_tmp.insert(r);
mods_tmp.insert(a);
}
mods.insert(mods_tmp.begin(), mods_tmp.end());
mods_tmp.clear();
}
printf("NO\n");
}
return ;
}

  (2)好理解点,中规中矩(218ms)

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
using namespace std; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE int n, m;
while (scanf("%d%d", &n, &m) != EOF) { int a, r;
set<int> mods;
set<int> mods_tmp; mods.insert();
for (int i = ; i < n; i++) {
scanf("%d", &a);
for (set<int>::iterator it = mods.begin(); it != mods.end(); ++it) {
int r = (*it + a) % m;
if (r == ) {
printf("YES\n");
return ;
}
mods_tmp.insert(r);
mods_tmp.insert(a);
}
mods.insert(mods_tmp.begin(), mods_tmp.end());
mods_tmp.clear();
}
printf("NO\n");
}
return ;
}

codeforces 577B. Modulo Sum 解题报告的更多相关文章

  1. Codeforces 577B Modulo Sum

    http://codeforces.com/problemset/problem/577/B 题意:有n个数,求有无一个子序列满足和是m的倍数 思路:用模下的背包做,发现n是十的六次方级别,但是有个神 ...

  2. Codeforces 577B Modulo Sum:数学 结论【选数之和为m的倍数】

    题目链接:http://codeforces.com/problemset/problem/448/C 题意: 给你n个数字,给定m. 问你是否能从中选出若干个数字,使得这些数字之和为m的倍数. 题解 ...

  3. codeforces D. Toy Sum 解题报告

    题目链接:http://codeforces.com/problemset/problem/405/D 题目意思:从 1 - 1000000 中选择 n 个数:x1,x2,...,xn,对 x1-1, ...

  4. Codeforces Round 665 赛后解题报告(暂A-D)

    Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...

  5. Codeforces Round 662 赛后解题报告(A-E2)

    Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...

  6. LeetCode 2 Add Two Sum 解题报告

    LeetCode 2 Add Two Sum 解题报告 LeetCode第二题 Add Two Sum 首先我们看题目要求: You are given two linked lists repres ...

  7. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  8. LeetCode: Combination Sum 解题报告

    Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...

  9. Codeforces Round #277.5 解题报告

    又熬夜刷了cf,今天比正常多一题.比赛还没完但我知道F过不了了,一个半小时贡献给F还是没过--应该也没人Hack.写写解题报告吧= =. 解题报告例如以下: A题:选择排序直接搞,由于不要求最优交换次 ...

随机推荐

  1. 【转】CSS3动画帧数科学计算法

    本文来源于:财付通TID 原作者:bboy90 总结都浓缩在这个工具里了,想知道工具的地址或想窥探工具诞生的趣事请往下看 . —————————————————————–     华丽丽的开篇     ...

  2. JavaScript中 window.parent 、window.top、window.self代表的含义

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法 ...

  3. EF上下文管理

  4. IIS服务器运行一段时间后卡死,且无法打开网站(IIS管理无响应,必须重启电脑)

    问题描述: 公司希望使用IIS配合网站显示一些订单跟进的情况并展示出来,所以我们在一台演示的Win7 Pro电脑上安装了IIS,但使用了一段时间后发现每过几天页面就无法正常访问了,而且打开IIS管理器 ...

  5. 开机自动连接/断开VPN 批处理

    或许大家在工作或生活中有接触到VPN,如果使用Windows自带的VPN来连接,每次开机要像宽带拨号那样,右击该VPN连接图标,然后选择“连接”(如果未记住密码甚至还要输入密码),然后点击确定,有点麻 ...

  6. linux 驱动 工作队列

    http://blog.sina.com.cn/s/blog_78d30f6b0102uyaf.html http://blog.csdn.net/lyc_stronger/article/detai ...

  7. STAR-H1208M集线器不支持同时挂载多个nfs

    今天在两个触摸屏上都加入了开机加载nfs的操作. 没想到会出现以下错误: pmap_getmaps.c: rpc problem: RPC: Unable to receive; errno = Co ...

  8. ajax读取XML文本(如读取城市)

    //加载城市 function loadArea_pep() { $.ajax({ url: "/xmlFile/crty.xml", success: function (res ...

  9. 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18) eoe上看到的

    ===============eoeAndroid社区推荐:======================= 1.Android开发新浪面试题[开发者必看哦]下载地址 http://www.eoeand ...

  10. 备份Oracle数据库的脚本

    @echo off goto bakoracle :bakoracle echo. echo ★☆★  自动备份Oracle数据库   ★☆★ echo. set backpath=E:\Oracle ...