POJ 2549 Sumsets(折半枚举+二分)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 11946 | Accepted: 3299 |
Description
Given S, a set of integers, find the largest d such that a + b + c = d where a, b, c, and d are distinct elements of S.Input
Output
Sample Input
5
2
3
5
7
12
5
2
16
64
256
1024
0
Sample Output
12
no solution
Source
题意
给你一个公式a+b+c=d,让你在同一个集合(元素不同)内满足该条件时d的最大值,注意a b c d均不同。
思路
网上折半搜索的思路一般是将a+b+c=d拆分成 a+b=d-c
优秀的代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf = -;
int a[];
int main()
{
int n;
while (cin>>n&&n)
{
for (int i = ; i < n; i++)
cin >> a[i];
sort(a, a + n);//从小到大
n--;
int ans = inf;
for (int i = n; i >= ; i--)
{
for (int j = n; j >= ; j--)
{
if (i == j)
continue;
int sum = a[i] - a[j];
for (int l = , r = j - ; l<r;)//剩下用二分
{
if (a[l] + a[r] == sum)
{
if (l != i && r != i)
{
ans = a[i];
break;
}
}
if (a[l] + a[r]>sum)
r--;
else
l++;
}
if (ans != inf)
break;
}
if (ans != inf)
break;
}
if (ans == inf)
printf("no solution\n");
else
printf("%d\n", ans);
}
return ;
}
将a+b,c-d看成两个序列,然后二分查找。 注意不要忘记去重
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<iostream>
#include<cmath>
#include<map>
#include<list>
#include<stack>
typedef long long ll;
using namespace std; int n;
int a[]; struct node{
int i,j;
int val;
}b[*]; bool cmp(node a,node b)
{
return a.val<b.val;
} bool comp1(node a,int b)
{
return a.val<b; // 找到第一个val>=b的结构体元素
} bool comp2(node a,int b)
{
return a.val<=b; // 找到第一个val>b的结构体元素
} int main()
{
while(scanf("%d",&n)==&&n)
{
int i,j,k,m,t;
for(i=;i<n;i++)
scanf("%d",a+i);
sort(a,a+n); int len=;
for(i=;i<n;i++)
{
for(j=i+;j<n;j++)
{
if(a[i]!=a[j]) //这里直接判断一下 不同的话再存 以后就可以减少这部判断啦
{
b[len].i=i;
b[len].j=j;
b[len].val=a[i]+a[j]; //存储题意中的 a+b
len++;
}
}
}
sort(b,b+len,cmp); //根据a+b的值从小到大排序 bool flag=false;
for(i=n-;i>=;i--) //之前已经从小到大对sort了 所以直接从最大的开始
{
int d=a[i]; //我们要找的d
for(j=;j<i;j++)
{
if(d!=a[j]) //d不能等于c
{
int cd=d-a[j]; //cd的值就相当于d-c
node* p1=lower_bound(b,b+len,d-a[j],comp1);
node* p2=lower_bound(b,b+len,d-a[j],comp2);//注意我写的两个函数comp, 而且都是作为lower_bound的参数
if(p2-p1!=) //说明存在 a+b==d-c
{
while(p1!=p2) //还要判断一下a,b,c,d是否都不相同
{
if(a[p1->i]!=a[j]&&a[p1->i]!=a[i]&&a[p1->j]!=a[j]&&a[p1->j]!=a[i])
{
flag=true; //符合题意 直接跳出
break;
}
p1++;
}
}
}
if(flag) //符合题意 直接跳出
break; }
if(flag)break; //符合题意 直接跳出 }
if(flag)printf("%d\n",a[i]); //符合题意 直接输出d 也就是a[i]
else printf("no solution\n"); }
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=+;
ll t[maxn],d[maxn*maxn];
struct node
{
ll sum;
int use1,use2;
} c[maxn*maxn];
bool cmp(const node& a,const node& b)
{
return a.sum<b.sum;
}
int main()
{
int n;
while(~scanf("%d",&n),n)
{
int i,j,s=;
for(i=; i<n; i++)
scanf("%lld",&t[i]);
sort(t,t+n);
for(i=; i<n; i++)
for(j=; j<n; j++)
if(i!=j)
{
c[s].sum=t[i]+t[j];
c[s].use1=i;
c[s++].use2=j;
}
sort(c,c+s,cmp);
for(i=; i<s; i++)
d[i]=c[i].sum;
ll ma=-1e17;
for(i=; i<n; i++)
{
for(j=n-; j>=; j--)
{
if(i!=j&&t[j]>ma)
{
ll u=-(t[i]-t[j]);
int id1=lower_bound(d,d+s,u)-d;
int id2=upper_bound(d,d+s,u)-d-;
for(int k=id1;k<id2;k++)
{
int a=c[k].use1,b=c[k].use2;
if(a!=i&&a!=j&&b!=i&&b!=j)
{
ma=t[j];break;
}
}
}
}
}
if(ma!=-1e17)printf("%lld\n",ma);
else printf("no solution\n");
}
return ;
}
POJ 2549 Sumsets(折半枚举+二分)的更多相关文章
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
1514: Packs Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 61 Solved: 4[Submit][Status][Web Board] ...
- POJ 2549 Sumsets
Sumsets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10593 Accepted: 2890 Descript ...
- 【折半枚举+二分】POJ 3977 Subset
题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...
- POJ 3977:Subset(折半枚举+二分)
[题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...
- Subset POJ - 3977(折半枚举+二分查找)
题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...
- POJ 2785 4 Values whose Sum is 0(折半枚举+二分)
4 Values whose Sum is 0 Time Limit: 15000MS Memory Limit: 228000K Total Submissions: 25675 Accep ...
- Subset---poj3977(折半枚举+二分查找)
题目链接:http://poj.org/problem?id=3977 给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的: n<=35,|a[i]| ...
- Codeforces H. Prime Gift(折半枚举二分)
题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...
随机推荐
- 【Html 学习笔记】第五节——表格
表格也是日常用到的. 普通表格:<table> 表格边框:border 表头:th 表格标题:caption 横/纵向合并的单元格:colspan .rawspan 表格内标签: 单元格间 ...
- 迁移到阿里云后,NTKO控件报存word 报文件存取错误,请检查网络传输。
解决办法:安装如下组件即可!
- Django部署时为什么要用 uWSGI与 Nginx? 以及 WSGI,uwsgi等协议
Django框架的服务器架构一般是 Nginx + uWSGI + Django (1)一些基本概念 1 WSGI协议,uwsgi协议 WSGI协议(通讯协议):Python用于Web开发的协议(用于 ...
- javaScript高程笔记--最佳实践
1.可维护性 <1>什么是可维护的代码 (1)可理解性 (2)直观性 (3)可适应性 (4)可扩展性 (5)可调试性 <2>代码约定 (1)可读性---适当的进行注释[函数和方 ...
- 《Drools7.0.0.Final规则引擎教程》第4章 4.5RHS语法
RHS语法 使用说明 RHS是满足LHS条件之后进行后续处理部分的统称,该部分包含要执行的操作的列表信息.RHS主要用于处理结果,因此不建议在此部分再进行业务判断.如果必须要业务判断需要考虑规则设计的 ...
- 测试实战经验之checklist篇20140905
我们测试中,在各个环节应该有自己的一个checklis来帮助我们梳理我们要做什么,该做什么,以下是我的一个小总结: 1.在测试前我们需要做的: 2.在拿到测试包后我们该做的 3.测试通过后我们该做的 ...
- 解决visual studio2017没有系统类和方法注释的问题
好几次碰到这种情况了,每次都得稍微查一查才能解决这个问题,相信也有不少人遇到这个问题,在对方法还不是很熟练的时候,将鼠标放置到方法上去,就会有信息提示是一件非常方便的事情,本文的解决方法同样适用于只显 ...
- I.MX6 U-Boot mkconfig hacking
/**************************************************************************** * I.MX6 U-Boot mkconfi ...
- 【pandas】pandas.to_datatime()---时间格式转换
标准时间格式:2012-12-21 时间转换函数:pandas.to_datatime() # -*- coding: utf- -*- # 生成数据 import pandas as pd data ...
- Java [Leetcode 384]Shuffle an Array
题目描述: Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. i ...