NYOJ138 找球号(二)(哈希,位运算,vector,二分)

2023-10-06 01:01

本文主要是介绍NYOJ138 找球号(二)(哈希,位运算,vector,二分),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:

找球号(二)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 5
描述
在某一国度里流行着一种游戏。游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是"ADD",表示向空箱子里放m(0<m<=100)个球,另一种是"QUERY”,表示说出M(0<M<=100)个随机整数ki(0<=ki<=100000100),分别判断编号为ki 的球是否在这个空箱子中(存在为"YES",否则为"NO"),先答出者为胜。现在有一个人想玩玩这个游戏,但他又很懒。他希望你能帮助他取得胜利。
输入
第一行有一个整数n(0<n<=10000);
随后有n行;
每行可能出现如下的任意一种形式:
第一种:
一个字符串"ADD",接着是一个整数m,随后有m个i;
第二种:
一个字符串"QUERY”,接着是一个整数M,随后有M个ki;

输出
输出每次询问的结果"YES"或"NO".
样例输入
2
ADD 5 34 343 54 6 2
QUERY 4 34 54 33 66
样例输出
YES
YES
NO
NO
代码1( 未AC,但是代码正确,二分法):

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int a[10000001];
int erfen(int index,int m)
{int mid;int start=0,end=m-1;while(start<=end){mid=(start+end)/2;if(a[mid]>index){end=mid-1;}else if(a[mid]<index){start=mid+1;}elsereturn 1;}return 0;
}
int main()
{int n;int x=0;scanf("%d",&n);char b[15];while(n--){memset(b,'\0',sizeof(b));scanf("%s",b);if(strcmp(b,"ADD")==0){int m;scanf("%d",&m);for(int i=0; i<m; i++)scanf("%d",&a[x++]);}else if(strcmp(b,"QUERY")==0){int k;scanf("%d",&k);sort(a,a+x);while(k--){int m;scanf("%d",&m);printf("%s\n",erfen(m,x)?"YES":"NO");}}}return 0;
}

代码2( vector容器/ac):

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;
vector<bool>a(100000001);
int main()
{int n;int x=0;scanf("%d",&n);char b[15];while(n--){memset(b,'\0',sizeof(b));scanf("%s",b);if(strcmp(b,"ADD")==0){int m,n;scanf("%d",&m);while(m--){scanf("%d",&n);a[n]=true;}}else if(strcmp(b,"QUERY")==0){int k;scanf("%d",&k);while(k--){int m;scanf("%d",&m);printf("%s\n",a[m]==true?"YES":"NO");}}}return 0;
}
代码3( 哈希)://代码来自于别人

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<time.h>
#include<algorithm>
using namespace std;#define N 1000010
#define CLR(arr, what) memset(arr, what, sizeof(arr))const int fib = 111123;
int Key[N], Head[N], Next[N];
int top;void add(int n)
{int temp;temp = n % fib;Key[top] = n;Next[top] = Head[temp];Head[temp] = top;top++;
}int main()
{int ncase;char str[8];int num, number;bool flag;CLR(Key, 0);CLR(Head, -1);top = 0;flag = false;scanf("%d", &ncase);while(ncase--){scanf("%s", str);if(str[0] == 'A'){scanf("%d", &num);for(int i = 0; i < num; ++i){scanf("%d", &number);add(number);}}else{scanf("%d", &num);for(int i = 0; i < num; ++i){scanf("%d", &number);int temp = number % fib;for(int j = Head[temp]; j != -1; j = Next[j])if(Key[j] == number){flag = true;break;}printf(flag == true ? "YES\n" : "NO\n");flag = false;}}}return 0;
}
ps: 虽然名字很高大上,但是这种方法我并不会。。。以后会了再补

代码4( 位运算版)://代码来自于别人

#include<stdio.h>  
unsigned int hash[3125005] = {0};  
int main()  
{  int i,a,t,n;  char str[10];  scanf("%d", &t);  while(t--)  {  scanf("%s %d", str, &n);  if(str[0] == 'A')  {  for(i = 0; i < n; ++i)  {  scanf("%d", &a);  hash[a / 32] |= 1 << (a % 32);  }  }  else if(str[0] == 'Q')  {  for(i = 0; i < n; ++i)  {  scanf("%d", &a);  if(hash[a / 32] & (1 << (a % 32)))  printf("YES\n");  else  printf("NO\n");  }  } }return 0;  
}  

ps: 3125005怎么来的?因为最大值是10^7+10。用32来除法散列,(10^7+10)/32 ~~3125000.3125,所以取3125005。为什么是用32来散列呢?数据说了数值不会超过32位。虽然是这样,但是这种方法还是很难理解


这篇关于NYOJ138 找球号(二)(哈希,位运算,vector,二分)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/152454

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3104 二分答案

题意: n件湿度为num的衣服,每秒钟自己可以蒸发掉1个湿度。 然而如果使用了暖炉,每秒可以烧掉k个湿度,但不计算蒸发了。 现在问这么多的衣服,怎么烧事件最短。 解析: 二分答案咯。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <c

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta