51nod 1090 3个数和为0 & 51nod 1267 4个数和为0(标记二分)
来源:互联网 发布:ubuntu怎么扩展内存 编辑:程序博客网 时间:2024/06/05 02:31
题目意思:
3个数的和为0:
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1090
给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等。从中找出所有和 = 0的3个数的组合。如果没有这样的组合,输出No Solution。如果有多个,按照3个数中最小的数从小到大排序,如果最小的数相等则按照第二小的数排序。
Input
第1行,1个数N,N为数组的长度(0 <= N <= 1000)第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)
Output
如果没有符合条件的组合,输出No Solution。如果有多个,按照3个数中最小的数从小到大排序,如果最小的数相等则继续按照第二小的数排序。每行3个数,中间用空格分隔,并且这3个数按照从小到大的顺序排列。
Input 示例
7-3-2-10123
Output 示例
-3 0 3-3 1 2-2 -1 3-2 0 2-1 0 1
题目分析:
此题可以二分,首先计算任意两个数的和存到数组b中,进行排序a(原数组)和b数组,进行判断a[i=0]+b[j=(n*(n-1))]=0?,如果三个数两两不等且等于0,则存到结果数组,(保证输出时结果不重复),最后输出结果集。详见代码,写的有点乱,望见谅!
AC代码:
<span style="font-size:18px;">#include<iostream>#include<algorithm>#include<cmath>#define MAX 1001using namespace std;int a[MAX],b[3];struct node{ int si,sj;}s[MAX*(MAX-1)];struct Snode{ int si,sj,sk;}p[MAX*(MAX+5)];int cmp1(node a,node b){ if(a.si+a.sj<=b.si+b.sj) return 1; return 0;}int cmp2(Snode a,Snode b){ if(a.si<b.si) return 1; else if(a.si==b.si&&a.sj<b.sj) return 1; else if(a.si==b.si&&a.sj==b.sj&&a.sk<b.sk) return 1; return 0;}int main(){ int n; while(cin>>n){ int k=0; for(int i=0;i<n;i++){ cin>>a[i]; for(int j=0;j<i;j++){ s[k].si=a[i]; s[k++].sj=a[j]; } } sort(a,a+n); sort(s,s+k,cmp1); int i=0,j=k-1,ok=1,kk=0; while(i<n&&j>=0){ if(s[j].si+s[j].sj+a[i]==0){ if(a[i]!=s[j].si&&a[i]!=s[j].sj){ ok=0; b[0]=a[i]; b[1]=s[j].si; b[2]=s[j].sj; sort(b,b+3); p[kk].si=b[0]; p[kk].sj=b[1]; p[kk++].sk=b[2]; } j--; } else if(s[j].si+s[j].sj+a[i]<0){ i++; } else if(s[j].si+s[j].sj+a[i]>0){ j--; } } //cout<<kk<<endl; sort(p,p+kk,cmp2); if(ok) cout<<"No Solution"<<endl; else{ cout<<p[0].si<<" "<<p[0].sj<<" "<<p[0].sk<<endl; for(i=1;i<kk;i++){ if(p[i].si==p[i-1].si&&p[i].sj==p[i-1].sj&&p[i].sk==p[i-1].sk) continue; else cout<<p[i].si<<" "<<p[i].sj<<" "<<p[i].sk<<endl; } } } return 0;}</span>
四个数的和是否为0
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1267
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。
Input
第1行,1个数N,N为数组的长度(4 <= N <= 1000)第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)
Output
如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。
Input 示例
5-11-524
Output 示例
Yes
题目分析:
本题和三个数的和为0,算法一样,只是这里数组b和自己求和是否为0,比较是否用两两相等的时候,需要比较下标,只要相加是将两个数的下标对应存起来即可。
AC代码:
<span style="font-size:18px;">/** *序列中可能有重复的数 *首先两个数相加为一个序列,再用这个序列和和本序列相加是否等于0 *判断是注意比较是否四个数是否相等,由于可能有重复的数,只能用 *位置判断,及记录两个数的位置下标进行比较, *记过等于0且不相等YES,否则NO */#include<iostream>#include<algorithm>#include<cmath>#define MAX 1001using namespace std;int a[MAX];struct node{ int i,j; int sum;}s[MAX*(MAX-1)];int cmp1(node a,node b){ if(a.sum<=b.sum) return 1; return 0;}int main(){ int n; while(cin>>n){ int k=0; for(int i=0;i<n;i++){ cin>>a[i]; for(int j=0;j<i;j++){//合为两个数的和 s[k].i=i; s[k].j=j; s[k++].sum=a[i]+a[j]; } } sort(s,s+k,cmp1); int i=0,j=k-1,ok=1; while(i<=j){ if(s[i].sum+s[j].sum==0){ if(s[i].i!=s[j].i&&s[i].i!=s[j].j&&s[i].j!=s[j].i&&s[i].j!=s[j].j){//四个下标任意不相等 ok=0; break; } i++; j--; } else if(s[i].sum+s[j].sum<0){ i++; } else if(s[i].sum+s[j].sum>0){ j--; } } if(ok) cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0;}</span>
0 0
- 51nod 1090 3个数和为0 & 51nod 1267 4个数和为0(标记二分)
- 51nod 1267 4个数和为0(二分)
- 51Nod 1267 4个数和为0(二分)
- 51nod 1090 3个数和为0(二分)
- 51nod 1090 3个数和为0(二分)
- 51Nod 1090 3个数的和为0 && 1267 4个数的和为0 (排序+二分)
- 51NOD 1267 4个数和为0(二分 + 排序)
- 51nod 1267 4个数和为0 哈希+二分
- 51Nod 1267 4个数和为0 ( 二分
- 51nod 1267 4个数和为0 二分查找
- 51nod 1090 3个数和为0 (二分_stl)
- 51Nod 1090 3个数和为0 (二分
- 51nod 1090 3个数和为0 二分暴力。
- 51NOD 1090 三个数和为0 1267 4个数和为0 二分答案
- 51nod -1090 . 3个数和为0 && 1267 . 4个数和为0
- 3个数和为0 51Nod
- 51nod 1267 4个数和为0(暴力)
- 51nod 1267 4个数和为0(二分查找)好题!!!
- Java 安全模型介绍
- 系统集成部和行业应用部的职责
- 使用cl编译的步骤
- Prime算法
- What technical details should a programmer of a web application consider before making the site publ
- 51nod 1090 3个数和为0 & 51nod 1267 4个数和为0(标记二分)
- 【BZOJ】【P3275】【Number】【题解】【最小割】
- Python笔记(20141130)
- 分支-07. 比较大小(10)
- HDU 5125 magic balls
- 【UNIX】什么是线程的同步和互斥
- 7个示例科普CPU Cache
- Android图灵机器人的实现(一)
- Linux下Python获取IP地址的代码