sicily 1047(数学)
来源:互联网 发布:java 制作图片 编辑:程序博客网 时间:2024/05/22 08:22
题目链接:sicily 1047
解题思路:
题意很简单,即需要把一串连续的不超过25个的整数分成A、B两部分,分别相加得到两个数sumA、sumB,使得a+sumA=b+sumB。
一眼看过是感觉是0-1背包,但是其实不太一样,因为所有的整数是连续的,所以可以有更方便的方法解决。
假设第一个数为low,最后一个数为high,我们可以得到如下定理:
当A部分有 i 个数时,当且仅当(low+low+i-1)*i/2 <= sumA <= (high+high-i+1)*i/2时,存在满足题意的组合。
于是我们的算法就是枚举A部分有不同个数时,检查不等式组是否被满足。注意首先需要判断a+sumA+b+sumB是否为偶数,并且sumA与sumB不能为负数,详见代码。
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int a,b,low,high;int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d %d %d %d",&a,&b,&low,&high); if(b<a){ swap(a,b); } int flag=0,sum=a+b,tmp; sum += (low+high)*(high-low+1)/2; tmp = sum/2; if(sum%2==0&&tmp>=a) { tmp -= a; for(int i=0;i<=high-low+1;i++) { int low_val = (low+low+i-1)*i/2, high_val = (high+high-i+1)*i/2; if(tmp>=low_val&&tmp<=high_val){ flag=1; break; } } } if(flag) printf("possible\n"); else printf("not possible\n"); } return 0;}
总结:
好题!懂得复杂算法之后不能忽视问题中的数学属性。
0 0
- sicily 1047(数学)
- Sicily 1047 Super Snooker
- Sicily 1047 Super Snooker
- sicily 1381(高精度)
- sicily 1140(搜索)
- sicily 1071(搜索)
- sicily题目分类(转)
- sicily题目分类(转)
- Sicily 1735 Encryption (模拟)
- sicily 13602(动态规划)
- sicily 1176 (动态规划)
- sicily 1419(动态规划)
- sicily 1077(动态规划)
- sicily 1019(动态规划)
- sicily 1264(动态规划)
- 最小和(sicily算法)
- sicily 1342 (0/1背包问题)
- Sicily 4189 统计数字(难得水题)
- UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)
- 算法学习笔记之约瑟夫环问题
- Android学习笔记3:使用日志工具
- 《剑指offer》01 赋值运算符函数
- Android基础:动画三:属性动画
- sicily 1047(数学)
- ZOJ - 3875 Lunch Time (模拟)水
- c++写windows服务程序
- Android学习笔记4:探究活动1
- Codeforces Round 335 (Div 2) D. Lazy Student【构造 脑洞 最小生成树】
- HDOJ1203
- HBase的javaApi一个应用(创建删除表等)
- UVa 524 Prime Ring Problem
- 启动报错com/opensymphony/xwork2/spring/SpringObjectFactory.java:245:-1