【贪心(?)】2017-03-19realseq
来源:互联网 发布:免费下载听书软件 编辑:程序博客网 时间:2024/04/29 11:31
分析:
本题解并不严谨,如有证明或bug请指出(最好附反例)
首先,题目中强调了最多包含五位小数,那么就可以将每一个值乘上100000
(注意:乘了100000转整数时候,一定要加0.1,否则会出现精度问题!!巨坑!!)
如果x只在[A,B]中出现了1次,那么就可以看作出现的那个数本身
如果出现了多次,那么一定是某两个数之差。、
因为k十分的小,只有50,所以两两之差最多有只有1000多个
因此,有可能为x的数,也就是可行解的集合最多也就1000多个值
同时,我们还要筛去一些不合法的值:
1、如果为两两之差产生的数,那么这两个数必须是差数的倍数(如3,5的差2就是不合法的,因为3,5不是2的倍数)
2、这个值在[A,B]内每一个倍数都必须出现过。
3、这个值的因数不存在于集合内(否则它一定没有他的因子优)
到这里,我们就得到了一个可行解的集合,现在的任务就是把这个集合尽量缩小。下面就是不科学的地方了:
把集合的值从小到大依次枚举(因为值小的覆盖的数量,一定比值大的多)
如果当前的值可以将覆盖的范围变大,那么就将这个数放入解集。
最后一步,在解集中再找一边,筛去多余的值(即删去这个数覆盖范围不变)
最后的解集就是答案
#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#define SF scanf#define PF printf#define MAXN 60using namespace std;int n;long long A,B,a[MAXN],al[MAXN*MAXN],vis[MAXN*MAXN],num[MAXN*MAXN],ans;long long print[MAXN*MAXN];vector<long long> pos;long long bit[MAXN];bool check(long long x){ for(int i=0;i<pos.size();i++) if(x%pos[i]==0) return 0; long long y=(A+x-1)/x; int j=1; for(;y*x<=B&&j<=n;y++){ for(;j<=n;j++) if(a[j]==y*x) break; if(n<j) break; } if(y<=B/x) return 0; return 1;}long long other(int x){ long long res=0; for(int i=0;i<ans;i++) if(i!=x) res=res|num[i]; return res;}int main(){ double x; long long tot=0; freopen("realseq.in","r",stdin); freopen("realseq.out","w",stdout); bit[0]=1; for(int i=1;i<=50;i++) bit[i]=bit[i-1]*2; SF("%d",&n); SF("%I64d%I64d",&A,&B); A*=100000; B*=100000; for(int i=1;i<=n;i++){ SF("%lf",&x); a[i]=1LL*(x*100000.0+0.5); } for(int i=1;i<=n;i++) for(int j=1;j<i;j++) if(a[i]%(a[i]-a[j])==0&&check(a[i]-a[j])){ pos.push_back(a[i]-a[j]); } for(int i=1;i<=n;i++){ int j=0; for(;j<pos.size();j++) if(a[i]%pos[j]==0) break; if(j==pos.size()){ PF("%I64d.",a[i]/100000); PF("%05I64d\n",a[i]%100000); } } sort(pos.begin(),pos.end()); for(int i=0;i<pos.size();i++){ for(int j=1;j<=n;j++){ if(a[j]%pos[i]==0) al[i]+=bit[j-1]; } } for(int i=0;i<pos.size();i++){ if((tot|al[i])>tot){ num[ans]=al[i]; print[ans++]=pos[i]; tot=tot|al[i]; } } for(int i=0;i<ans;i++) if(other(i)==tot) print[i]=-1; //PF("(%I64d)",tot) for(int i=0;i<ans;i++){ if(print[i]==-1) continue; PF("%I64d.",print[i]/100000); PF("%05I64d\n",print[i]%100000); }}
0 0
- 【贪心(?)】2017-03-19realseq
- 贪心!
- 贪心~
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 贪心
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- UART.c
- 538. Convert BST to Greater Tree 二叉搜索树转化为更大的树
- 临时备忘录
- 奇偶校验-华中科技大学计算机题
- 【贪心(?)】2017-03-19realseq
- 哲理故事(51)-一万小时定律(10000小时法则)
- 设计模式之工厂模式
- eclipse 运行c++代码
- 算法导论 练习题 3.2-5
- final关键字
- 华为OJ训练之0018-170105-字符串翻转(字符逆序题目)
- static作用(修饰函数、局部变量、全局变量)
- L2-011. 玩转二叉树