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

Several S, each consisting of a line containing an integer 1 <= n <= 1000 indicating the number of elements in S, followed by the elements of S, one per line. Each element of S is a distinct integer between -536870912 and +536870911 inclusive. The last line of input contains 0.

Output

For each S, a single line containing d, or a single line containing "no solution".

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(折半枚举+二分)的更多相关文章

  1. POJ 3977 Subset(折半枚举+二分)

    SubsetTime Limit: 30000MS        Memory Limit: 65536KTotal Submissions: 6754        Accepted: 1277 D ...

  2. CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。

    1514: Packs Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 61  Solved: 4[Submit][Status][Web Board] ...

  3. POJ 2549 Sumsets

    Sumsets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10593   Accepted: 2890 Descript ...

  4. 【折半枚举+二分】POJ 3977 Subset

    题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...

  5. POJ 3977:Subset(折半枚举+二分)

    [题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...

  6. Subset POJ - 3977(折半枚举+二分查找)

    题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...

  7. POJ 2785 4 Values whose Sum is 0(折半枚举+二分)

    4 Values whose Sum is 0 Time Limit: 15000MS   Memory Limit: 228000K Total Submissions: 25675   Accep ...

  8. Subset---poj3977(折半枚举+二分查找)

    题目链接:http://poj.org/problem?id=3977 给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的: n<=35,|a[i]| ...

  9. Codeforces H. Prime Gift(折半枚举二分)

    题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...

随机推荐

  1. SpringInAction--自动化装配Bean(显示装配之xml配置)

    Spring在配置时候有三种方案可选 1.在xml中进行显示配置 2.在java中进行显示配置 3.隐式的Bean发现机制和自动装配 今天学习的 第一种—— 在xml中进行显示配置 老规矩 先创建 C ...

  2. 字符串-----KMP竟然是18禁

    今天学了一下午字符串,讲到结束也没讲KMP.有人问老师为什么不讲,老师来一句:字符串noip不考,而且还是18禁,自然不讲.[手动滑稽] 所以我也不讲.[微笑] 1.表达式树 表示3+5*8 最后计算 ...

  3. LaText中插入带上下限的求和符号

    效果如下: LaTex命令如下: \begin{equation} \label{8} z_{i}(k+1)=\sum_{j\in N_{i}(k)} a_{ij}(k)z_{i}(k),z_{i}( ...

  4. 配置mysql 允许远程连接

    今天折腾了好常时间远程连接mysql ,在云服务器里面打开了3306端口,使用了service mysql status查看到mysql进程正常. netstat -anp | grep mysql ...

  5. Android支持Split Apks后,如何获得指定包名下的所有类

    从Android5.0以后,支持多个apk动态部署,这导致以前通过单一apk获取包路径下的所有类的方法失效,不过稍微修改一下原先的代码就可以,代码如下 public static final List ...

  6. flowable EngineConfiguration的实现分析(2)

    EngineConfiguration的实现类是一个抽象类:AbstractEngineConfiguration 一.引擎配置的分类 继承 AbsractEngineConfiguration的子类 ...

  7. iOS:Core Data 中的简单ORM

    我们首先在xcdatamodel文件中设计我们的数据库:例如我建立一个Data的实体,里面有一个String类型的属性name以及一个Integer类型的num: 然后选中Data,添加文件,选择NS ...

  8. IE中拖放问题

    1.所有的元素上都能绑定放置目标的事件,但并不保证此元素是有效的放置对象. 默认情况下,IE中只有文本框(<input/>或<textarea/>)是网页上唯一有效的放置目标. ...

  9. Uoj 22 外星人

    Uoj 22 外星人 注意到一个数只有 \(\%\) 了小于等于自己的数时,才可能有变化,否则可以随意安排,不会对最后最优解造成影响. 用 \(f[x]\) 表示给一个数 \(x\) ,仅用 \(a[ ...

  10. LOJ2500 NOIP2014 飞扬的小鸟 【背包DP】*

    LOJ2500 NOIP2014 飞扬的小鸟 LINK 题目大意就是说有n个柱子,在每一秒你可以选择不点下降高度y和点p次上升x∗p,若果当前位置加上x∗p大于上界m,就会停在m. 如果可以成功穿越所 ...