POJ 2785 有多少种4个数相加等于0的方案(二分查找 or hash)

文章目录

    • 1.二分查找法
      • 1.1 思路:
      • 1.2 AC代码
    • 2.hash查找法
      • 2.1 思路:
      • 2.2 Wrong Answer 代码
      • 2.3 Time Limit Exceeded 代码
      • 2.4 偷懒失败,hash_map在poj中不存在
      • 2.5 哈希表+二叉查找树(超时)
      • 2.6 AC代码(哈希+数组法)

题目链接: http://poj.org/problem?id=2785

题目大意:给定不超过4000行4个数,每列挑出来1个,使之和为0,有多少种方案。

1.二分查找法

1.1 思路:

  • 对左边两列的所有和求出来,右边两列所有的和的求出来再取负
  • 右侧两列的值排序(进行二分查找)
  • 对左边所有的和在右边的和中进行二分查找,并查找前后都满足要求的,计数即得答案
    在这里插入图片描述

1.2 AC代码

/*** @description: 求四个数相加等于0的组合种数* @author: michael ming* @date: 2019/5/8 22:18* @modified by:*/
#include <iostream>
#include <memory.h>
#include <algorithm>using namespace std;
int a[4001], b[4001], c[4001], d[4001];
int ab[4000*4000+1], cd[4000*4000+1];   //存储a+b,c+d
int findSameValue(int value, int maxindex)//二分查找
{int low = 0, high = maxindex, mid, index, count=0;while(low <= high){mid = low + (high - low)/2;if(value == cd[mid])    //查找前后满足要求的个数{index = mid - 1;while(index >= 0 && value == cd[index--])count++;index = mid + 1;while(index <= high && value == cd[index++])count++;return count + 1;}else if(value < cd[mid])high = mid - 1;elselow = mid + 1;}return 0;
}
int main()
{int line, k=0;cin >> line;memset(ab, 0, sizeof(ab));memset(cd, 0, sizeof(cd));for(int i = 0; i < line; ++i){cin >> a[i] >> b[i] >> c[i] >> d[i];}for(int i = 0; i < line; ++i){for(int j = 0; j < line; ++j){ab[k] = a[i]+b[j];cd[k++] = -(c[i]+d[j]);}}sort(cd,cd+k);  //二分查找的必要条件,有序int result = 0;for(int i = 0; i <= k-1; ++i)result += findSameValue(ab[i], k-1);cout << result << endl;return 0;
}

2.hash查找法

2.1 思路:

  • 对左边两列的所有和求出来,右边两列所有的和的求出来再取负
  • 对左侧两列的和存入哈希表
  • 对右边两列的和在哈希表中查找

2.2 Wrong Answer 代码

(未解决冲突,并且hash后的值可能为负,作为数组下标不行,所以错误)

/*** @description: 4个数和为0的方案数,哈希法* @author: michael ming* @date: 2019/5/9 22:30* @modified by: */
#include <iostream>
#include <memory.h>
using namespace std;
int a[4001], b[4001], c[4001], d[4001];
int ab[4000*4000+1], cd[4000*4000+1];   //存储a+b,c+d
int *hasht = new int[16000057];
int offset = 1000000000;
int hashfunc(int &value)
{int mod = 16000057;return (value%mod + value/mod)%mod;
}
int main()
{int line, k=0, value;cin >> line;memset(hasht, 0, sizeof(hasht));for(int i = 0; i < line; ++i){cin >> a[i] >> b[i] >> c[i] >> d[i];}for(int i = 0; i < line; ++i){for(int j = 0; j < line; ++j){ab[k] = a[i]+b[j];value = ab[k]+offset;hasht[hashfunc(value)]++;cd[k++] = -(c[i]+d[j]);}}int result = 0;for(int i = 0; i < k; ++i){value = cd[i]+offset;if(hasht[hashfunc(value)])result += hasht[hashfunc(value)];}cout << result << endl;delete [] hasht;return 0;
}

2.3 Time Limit Exceeded 代码

在这里插入图片描述

/*** @description: 4个数和为0的方案数,哈希法* @author: michael ming* @date: 2019/5/9 22:30* @modified by: */
#include <iostream>
#include <math.h>
using namespace std;
struct linkedNode   //链表节点
{pair<int, int> data;linkedNode *next;linkedNode():next(NULL), data(make_pair(0,0)){}
};
class linkedList    //链表
{
public:linkedNode *head;linkedList(){head = new linkedNode();  //表头哨兵}~linkedList(){delete head;}
};
class linkedHash
{
private:linkedList *htList; //散列表链表数组int bucket;  //散列表桶个数
public:linkedHash(int m):bucket(m){htList = new linkedList [bucket] ();}~linkedHash(){for(int i = 0; i < bucket; ++i){linkedNode *p = htList[i].head->next, *q = p;while(q != NULL){p = q;q = q->next;delete p;}}delete [] htList;}int hash(const int &key) const{return abs(key%bucket);   //留余数法}linkedNode* find(const int &x) const{int i = hash(x);linkedNode *p = htList[i].head->next, *q = htList[i].head;while(p && p->data.first != x){q = p;p = p->next;}return q;   //返回找到元素的前一个节点,或者没有找到,返回最后一个元素}linkedNode* insert(const int &x){int i = hash(x);linkedNode *p = htList[i].head, *q = p;while(q != NULL){p = q;q = q->next;if(q && q->data.first == x){q->data.second++;return q;}}p->next = new linkedNode();p->next->data.first = x;p->next->data.second++;return p->next;}
};
int a[4001], b[4001], c[4001], d[4001];
int ab[4000*4000+1], cd[4000*4000+1];   //存储a+b,c+d
int main()
{linkedHash ht(16000057);int line, k=0;cin >> line;for(int i = 0; i < line; ++i){cin >> a[i] >> b[i] >> c[i] >> d[i];}for(int i = 0; i < line; ++i){for(int j = 0; j < line; ++j){ab[k] = a[i]+b[j];ht.insert(ab[k]);cd[k++] = -(c[i]+d[j]);}}int result = 0;linkedNode* p;for(int i = 0; i < k; ++i){p = ht.find(cd[i])->next;if(p && p->data.first == cd[i])result += p->data.second;}cout << result << endl;return 0;
}

2.4 偷懒失败,hash_map在poj中不存在

在这里插入图片描述

/*** @description: 4个数和为0的方案数,哈希法* @author: michael ming* @date: 2019/5/9 22:30* @modified by: */
#include <iostream>
#include <hash_map>
//#include <unordered_map>
using namespace std;
int a[4001], b[4001], c[4001], d[4001];
int ab[4000*4000+1], cd[4000*4000+1];   //存储a+b,c+d
int main()
{__gnu_cxx::hash_map<int, int> ht;
//    std::unordered_map<int, int> ht;int line, k=0;cin >> line;for(int i = 0; i < line; ++i){cin >> a[i] >> b[i] >> c[i] >> d[i];}for(int i = 0; i < line; ++i){for(int j = 0; j < line; ++j){ab[k] = a[i]+b[j];ht[ab[k]]++;cd[k++] = -(c[i]+d[j]);}}int result = 0;for(int i = 0; i < k; ++i){result += ht[cd[i]];}cout << result << endl;return 0;
}

2.5 哈希表+二叉查找树(超时)

可能是建立二叉树插入节点new太耗时了。

/*** @description: 4个数和为0的方案数,哈希法* @author: michael ming* @date: 2019/5/9 22:30* @modified by:*/
#include <iostream>
#include <math.h>
using namespace std;
class BSTNode
{
public:int data, count;BSTNode *left, *right;BSTNode():count(1), left(NULL), right(NULL){}BSTNode(const int& d, BSTNode *l = NULL, BSTNode *r = NULL){data = d;   count = 1;   left = l;   right = r;}
};
class BST
{
private:BSTNode* root;int nodeLen;
public:BST():root(NULL){}~BST(){}void clear(BSTNode* nodeP){if(nodeP == NULL)return;clear(nodeP->left);clear(nodeP->right);delete nodeP;}BSTNode* get_root() const {  return root;    }bool isEmpty() const {  return root == NULL;    }BSTNode* search(const int& d) const{BSTNode* p = search(d, root);return p;}BSTNode* search(const int d, BSTNode* p) const{while(p != NULL){if(d == p->data)return p;else if(d < p->data)p = p->left;elsep = p->right;}return NULL;}void insert(const int d){BSTNode *p = root, *prev = NULL;while(p != NULL){prev = p;if(d < p->data)p = p->left;elsep = p->right;}if(root == NULL)root = new BSTNode(d);else if(d < prev->data)prev->left = new BSTNode(d);elseprev->right = new BSTNode(d);}
};class linkedHash
{
private:BST* ht_bstree; //散列表二叉树数组int bucket;  //散列表桶个数
public:linkedHash(int m):bucket(m){ht_bstree = new BST [bucket] ();}~linkedHash(){for(int i = 0; i < bucket; ++i){ht_bstree[i].clear(ht_bstree[i].get_root());}delete [] ht_bstree;}int hash(const int &key) const{return abs((((key+1000000000)%bucket)+1357)%bucket);   //留余数法}int find(const int &x) const{int i = hash(x);BSTNode *p = ht_bstree[i].search(x);if(p)return p->count;return 0;}void insert(const int x){int i = hash(x);BSTNode *p = ht_bstree[i].search(x);if(p)p->count++;elseht_bstree[i].insert(x);}
};
int a[4001], b[4001], c[4001], d[4001];
int ab[4000*4000+1], cd[4000*4000+1];   //存储a+b,c+d
int main()
{linkedHash ht(5000);    //多次调整括号内数值,超时或者内存超限int line, k=0;cin >> line;for(int i = 0; i < line; ++i){cin >> a[i] >> b[i] >> c[i] >> d[i];}for(int i = 0; i < line; ++i){for(int j = 0; j < line; ++j){ab[k] = a[i]+b[j];ht.insert(ab[k]);cd[k++] = -(c[i]+d[j]);}}int result = 0;for(int i = 0; i < k; ++i){result += ht.find(cd[i]);}cout << result << endl;return 0;
}

2.6 AC代码(哈希+数组法)

在这里插入图片描述

/*** @description: poj 2785 哈希法,数组实现* @author: michael ming* @date: 2019/5/20 18:17* @modified by: */
#include <iostream>
using namespace std;
int a[4001], b[4001], c[4001], d[4001];
const int hashtablesize = 20000001;//保证一定的富裕,装载因子0.75左右
int hasht[hashtablesize];
int count[hashtablesize];
int offset = 1000000000; // 该数 > 2^29(加上他后,就没有负数了,求模后比较方便使用下标值)
int hashfunc(int value)
{return value%hashtablesize;
}
int hashfunc_other(int value)
{return (value+3)%hashtablesize;
}
void insert(int num)
{int num_init = num;num = hashfunc(num+offset);while(hasht[num] != offset && hasht[num] != num_init)//解决冲突,不等于初始值(够不着的大数)(值改了,位子被占了),且不等于映射的值(冲突了),第一次进入循环,第一个条件肯定不满足。{num = hashfunc_other(num);//冲突了,继续寻找别的下标(换一个函数,不然相同的模在这可能无限循环)}hasht[num] = num_init;count[num]++;
}
int find(int num)
{int num_init = num;num = hashfunc(num+offset);while(hasht[num] != offset && hasht[num] != num_init)num = hashfunc_other(num);    //往下查找空位或者相等的值得位子if(hasht[num] == offset)    //找到的是空位子,则没有匹配的和等于0return 0;else    //找到了值相等的位子,把其对应的count位子里的个数返回return count[num];
}
int main()
{int line, k=0, value, i, j;cin >> line;for(i = 0; i < line; ++i){cin >> a[i] >> b[i] >> c[i] >> d[i];}for(i = 0; i < hashtablesize; ++i)hasht[i] = offset;  //hash表每个元素初始化为offsetfor(i = 0; i < line; ++i){for(j = 0; j < line; ++j){value = a[i]+b[j];insert(value);}}int result = 0;for(i = 0; i < line; ++i){for(j = 0; j < line; ++j){value = (-c[i]-d[j]);result += find(value);}}cout << result << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480281.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018最新阿里Java技术三面(已拿Offer):JVM+高并发性能+单点登录+微服务

一面 1.自我介绍 2.谈一个你觉得你学到最多的项目&#xff0c;使用了什么技术&#xff0c;挑战在哪里 3.Spring的bean的作用域&#xff1f;&#xff08;比如&#xff1a;singleton&#xff0c;prototype等&#xff09; 4.Spring的IOC实现原理&#xff1f;没有无参构造函数能…

论文浅尝 | 基于局内去噪和迁移学习的关系抽取

动机在远程监督任务中&#xff0c;除了语料的错误标注问题&#xff0c;还存在句内噪声单词过多的问题&#xff0c;即多数句子都存在一些与表达关系无关的词汇&#xff0c;这个问题未有人关注。当前研究的另一个问题是&#xff0c;句子特征抽取器采用随机初始化的方法&#xff0…

关于知识图谱,我们接下来该研究什么?斯坦福教授们给出了答案

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 舒意恒&#xff08;南京大学硕士生&#xff0c;知识图谱方向&#xff09;编 | 北大小才女小轶本文整理了斯坦福大学 CS 520 知识图谱研讨会课程的第 10 集的内容&#xff0c;主要是关于知识图谱未来的研…

POJ 2967 (水题,考察putchar()按位输入)

题目链接&#xff1a;http://poj.org/problem?id2967 题目大意&#xff1a; 给定系列长度&#xff0c;求是否有规定的三角形 &#xff08;不是所有的都可以组成三角形&&有至少一种组合可以组成三角形&#xff09;-> 打印通过&#xff0c;否则打印拒绝。 题目有时…

四大银行(工建农中)大数据进展如何?

原文地址&#xff1a;https://cloud.tencent.com/developer/article/1052576 中国建设银行中国建设银行信息技术管理部资深经理林磊明▼▼1、银行压力越来越大从十二五走到十三五期间&#xff0c;银行业面临的各方面的压力越来越大&#xff0c;从我们的年报数字可以看出去年四大…

论文浅尝 | 多内容实体和关系联合抽取的对抗训练

链接&#xff1a;https://arxiv.org/pdf/1808.06876.pdf动机Szegedy 在 14 年发现&#xff0c;对于图像分类问题的神经网络&#xff0c;若是在输入中人为的添加很小尺度的扰动&#xff0c;会让已经训练好的神经网络做出错误的判断&#xff0c;并且可能以很高的置信度输出。很多…

BAT面试进阶:最全Memcached面试30题含答案

【memcached面试题目】 Memcached服务在企业集群架构中应用场景? Memcached服务在不同企业业务应用场景中的工作流程? Memcached服务分布式集群如何实现&#xff1f; Memcached服务特点及工作原理是什么&#xff1f; Memcached内存管理机制原理&#xff1f; Memcached的…

一份从入门到精通NLP的完整指南 | NLPer

该小博主介绍本人&#xff1a;笔名zenRRan&#xff0c;方向自然语言处理&#xff0c;方法主要是深度学习。未来的目标&#xff1a;人工智能之自然语言处理博士。写公众号目的&#xff1a;将知识变成开源&#xff0c;让每个渴求知识而难以入门人工智能的小白以及想进阶的小牛找到…

论文浅尝 | 基于知识库的类型实体和关系的联合抽取

链接&#xff1a;http://hanj.cs.illinois.edu/pdf/www17_xren.pdfGitHub项目地址&#xff1a;https://github.com/INK-USC/DS-RelationExtraction动机现有的利用远程监督进行实体关系抽取的方法中存在以下三个问题&#xff1a;1、依赖事先训练的命名实体识别工具&#xff0c;而…

POJ 2255 Tree Recovery(已知前序中序,求后序)

1. 题目链接&#xff1a;http://poj.org/problem?id2255 2. 题目大意&#xff1a; 给定二叉树的前序和中序序列&#xff0c;输出其后序序列 3. 思考过程&#xff1a; 4. AC代码 /*** description: 给出前序和中序二叉树节点序列&#xff0c;求后序二叉树节点输出序列* auth…

美团内推:java高级开发(一面+二面+三面),面试58题实拍!

美团内推&#xff08;一面二面三面&#xff09;面试题目 美团一面&#xff08;电话&#xff09; 自我介绍 项目介绍 Redis介绍 了解redis源码么 了解redis集群么 Hashmap的原理&#xff0c;增删的情况后端数据结构如何位移 hashmap容量为什么是2的幂次 hashset的源码 …

ACL20 best paper荣誉提名 | DO NOT STOP Pre-training!

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | JayLou娄杰&#xff08;NLP算法工程师&#xff0c;信息抽取方向&#xff09;编 | 可盐可甜兔子酱在昨晚23点的best paper典礼上我惊了&#xff0c;这篇论文竟然获得了今年ACL2020 best paper荣誉提名..…

论文浅尝 | 对于知识图谱嵌入表示的几何形状理解

论文链接&#xff1a;http://anthology.aclweb.org/attachments/P/P18/P18-1012.Presentation.pdf发表会议&#xff1a;ACL 2018摘要知识图谱的嵌入表示在近几年已经成为一个非常活跃的研究领域&#xff0c;众多相关方法相继被提出&#xff0c;这些嵌入方法是将知识图谱中的实体…

数据结构--堆 Heap

文章目录1. 概念2. 操作和存储2.1 插入一个元素2.2 删除堆顶元素3. 堆排序&#xff08;不稳定排序&#xff09;3.1 建堆3.2 排序3.3 思考&#xff1a;为什么快速排序要比堆排序性能好&#xff1f;两者都是O(nlogn)4. 堆应用4.1 优先级队列4.2 用堆求 Top K&#xff08;前K大数据…

金融时报:人工智能在银行中的应用—对全球30家大型银行的调查

原文地址&#xff1a;https://cloud.tencent.com/developer/article/1144829 &#xff08;微信公众号 点滴科技资讯&#xff09;尽管银行业对新技术感到兴奋&#xff0c;但仍采取比较谨慎的方式。德意志银行首席执行官约翰•克莱恩&#xff08;John Cryan&#xff09;曾经提出将…

百度Java三面:现场面试39题目实拍含答案!

百度一面&#xff08;现场&#xff09; 自我介绍 Java中的多态 为什么要同时重写hashcode和equals Hashmap的原理 Hashmap如何变线程安全&#xff0c;每种方式的优缺点 垃圾回收机制 Jvm的参数你知道的说一下 设计模式了解的说一下啊 手撕一个单例模式 算法题目 手撕算…

CCKS2020事理图谱应用工作:刘焕勇等.面向开放文本的逻辑推理知识抽取与事件影响推理探索

一、背景介绍 第十四届全国知识图谱与语义计算大会(CCKS 2020) 11 月 12 日至 15 日在江西南昌举行&#xff0c;CCKS&#xff08;China Conference on Knowledge Graph and Semantic Computing&#xff09;是由中国中文信息学会语言与知识计算专委会定期举办的全国年度学术会议…

ACL20 Best Paper揭晓!NLP模型评价体系或将迎来重大转折

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 北大小才女小轶昨晚ACL2020的Main Conference落下帷幕&#xff0c;今年的最佳论文颁给了这篇《Beyond Accuracy: Behavioral Testing of NLP Models with CHECKLIST》。在ACL录用的778篇论文中&#xff…

论文浅尝 | 基于多模态关联数据嵌入的知识库补全

链接&#xff1a;https://arxiv.org/pdf/1809.01341.pdf动机&#xff08;摘要&#xff09;当前的知识库补全的方法主要是将实体和关系嵌入到一个低维的向量空间&#xff0c;但是却只利用了知识库中的三元组结构 (<s,r,o>) 数据&#xff0c;而忽略了知识库中大量存在的文本…

智能投顾原理与主流产品分析

原作者 王希&#xff0c;CFA&#xff0c;中国光大银行。核心观点&#xff1a;1、智能投顾的模式是通过技术实现财富管理的流程自动化&#xff0c;为客户定制FOF产品来投资并赚取管理费。目前尚未看出大数据分析、人工智能等技术在其中发挥出关键作用。2、智能投顾在美国的快速…