openjudge 两道hash题目

/*
 1 /*
 2 关键是两点可以确定一个正放心的另外两点
 3 主要得发现一个规律:当两点确认以后,正方形的位置其实就确认了(不过有两个)
 4 (这边的两个点是指正方形的一条边的两个点)
 5 所以枚举两个点o(n^2)然后就可以得出另外两个点的位置为(两种情况):
 6 s1:=b[i]-b[j]; s2:=c[i]-c[j];
 7 v1:=b[i]+s2; v2:=c[i]+(0-s1); v3:=b[j]+s2; v4:=c[j]+(0-s1);
 8 其中 v1 v2v3v4即为另外两个点的位置 还有另外一种为:
 9 v1:=b[i]+(0-s2); v2:=c[i]+s1; v3:=b[j]+(0-s2); v4:=c[j]+s1;
10 然后把二维转换为一维,为了避免负数,我把v1v2v3v4都加了20003,反正不影响结果
11 还有一点,由于正方形有四条边,我每条边都只做一遍,
12 //那么每个正方形都会算四次
13 //最后答案再除以四即可。
14 */
15 #include<cstdio>
16 #include<iostream>
17 #include<algorithm>
18 #include<cstring>
19 using namespace std;
20
21 struct H
22 {
23 int x,y;
24 }a[20000+1];
25
26 int num[2000+1];
27 bool b[2001+1][2001+1];
28 int hash[20001*2+1];
29 bool cmp(H a,H b){return a.x<b.x;}
30
31 int main()
32 {
33 int n;cin>>n;
34 while(n)
35 {
36 memset(b,false,sizeof(b));
37 memset(hash,0,sizeof(hash));
38
39 int tot=0;
40 for(int i=1;i<=n;i++)
41 scanf("%d %d",&a[i].x,&a[i].y),a[i].x+=20001,a[i].y+=20001,num[++tot]=a[i].x,num[++tot]=a[i].y;
42
43 sort(num+1,num+1+tot);
44 for(int i=1;i<=tot;i++)
45 if(num[i]!=num[i-1])
46 hash[num[i]]=hash[num[i-1]]+1;//每个点给个编号hash
47
48 for(int i=1;i<=n;i++)
49 b[hash[a[i].x]][hash[a[i].y]]=true;//有这个点
50
51 int ans=0;
52 sort(a+1,a+n+1,cmp);//横坐标排序
53 for(int i=1;i<=n;i++)//列举每条边
54 for(int j=1;j<=n;j++)
55 if(i!=j)
56 if(a[i].x<a[j].x&&a[i].y<=a[j].y)
57 if(a[j].y-a[j].x+a[i].x>=0&&a[i].y-a[j].x+a[i].x>=0)
58 if
59 (
60 b[ hash[a[j].x+a[j].y-a[i].y] ][ hash[a[j].y-a[j].x+a[i].x] ]
61 &&
62 b[ hash[a[i].x+a[j].y-a[i].y] ][ hash[a[i].y-a[j].x+a[i].x] ]
63 ) ans++;
64
65 printf("%d\n",ans);
66 scanf("%d",&n);
67 }
68 return 0;
69 }

给出平面上一些点的坐标,统计由这些点可以组成多少个正方形。注意:正方形的边不一定平行于坐标轴。

 1 #include<cstdio>
 2 #include<cstring>
 3 const int hs=1333331;//why!
 4 struct node
 5 {
 6 long long x,y,w;
 7 int nex;
 8 }l[1005*1005];
 9 int h[hs],cnt;
10 long long s[1005];
11 long long ans;
12 int n;
13 int i,a,b,c,d;
14 int p,he,cha;
15 int hash(long long x)//!!!!!!!!!!!!!!!!
16 {
17 return ((x%hs)+hs)%hs;
18 }
19 int main()
20 {
21 while(scanf("%d",&n)==1)
22 {
23 if(n==0)break;
24 for(i=1;i<=n;i++)
25 scanf("%lld",&s[i]);
26 memset(h,0,sizeof(h));
27 cnt=0;
28 for(a=1;a<=n;a++)
29 for(b=a+1;b<=n;b++)
30 {
31 cnt++;
32 he=hash(s[a]+s[b]);
33 l[cnt].x=a;
34 l[cnt].y=b;
35 l[cnt].w=s[a]+s[b];
36 l[cnt].nex=h[he];
37 h[he]=cnt;
38 }
39 ans=-536870913;
40 for(c=1;c<=n;c++)
41 for(d=1;d<=n;d++)
42 {
43 if(d==c)continue;
44 cha=hash(s[d]-s[c]);
45 for(p=h[cha];p!=0;p=l[p].nex)
46 {
47 if(l[p].w!=s[d]-s[c])continue;
48 if(l[p].x!=c&&l[p].x!=d&&l[p].y!=c&&l[p].y!=d&&s[d]>ans)
49 ans=s[d];
50 }
51 }
52 if(ans==-536870913)printf("no solution\n");
53 else printf("%lld\n",ans);
54 }
55 return 0;
56 }

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.输入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.输出For each S, a single line containing d, or a single line containing "no solution".

时间: 2024-10-14 02:43:45

openjudge 两道hash题目的相关文章

分享两道笔试题目

前几天,给成都的某家公司投了个简历,给发了两道笔试题目,与大家分享一下.附上自己的解题过程,写得不好的地方,还请博友多多指教. 一 .  设计程序输出销售及收费清单 一个电商平台对在其平台之上销售的除了书籍.食品以及药物以外的商品收取 10% 的费用.而对于进口的商品则额外收取 5% 的附加费用.对于平台抽取的费用计算时,舍入的规则是:对于 n% 抽取率,价格为 p的商品, np/100 的值就近舍入到 0.05(如: 7.125 -> 7.15, 6.66 -> 6.70 ). 卖家卖出一些

两道实分析题目

两道有意思的题目

碰到两道有意思的题目,记录一下. 题目一: 问,对于任意一个正整数,是否存在一个它的倍数全是由1和0组成? 例如: 1 * 1 = 1 2 * 5 = 10  (2的5倍是10,10由1和0组成) 3 * 37 = 111 (3 的 37 倍是111,111 全部由1组成) 4 * 25 = 100 (4 的 25 倍是100,100 由1和0组成) 5 * 20 = 100 (5 的 20 倍是100,100由1 和 0 组成) …… 现在需要判断,随便给一个正整数,是否存在一个它的倍数满足题

ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory:360K #include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> using namespace std; #define

课堂练习之每天出30道四则运算题目

1 /* 2 需求:每天出30道四则运算题目给小学生做 3 */ 4 5 class Rand 6 { 7 public static void sop(Object obj) 8 { 9 System.out.println(obj); 10 } 11 public static void main(String[] args) 12 { 13 sop("小学生二年级课后作业,每天30道四则运算练习:"); 14 15 int count = 0; 16 17 for (int i=

告诉我图样图森破的两道简单C++笔试题

今晚刷了一大堆的笔试题,中规中矩,但是有两道做得很快但是都错了的题目,印象深刻. (要找工作的大四渣有没有共鸣,在学校明明很努力,但是总是跟不上时代,没有厉害的项目,也没有过人的竞赛成绩,内推屡屡失败,前天阿里巴巴在线笔试也被虐死,真心迷惘,唯独刷题搞笔试了.) 第一道题是关于宏定义的. #include<iostream> using namespace std; #define fun(n) (n-1)*n int main() { int x=3; cout<<fun(x+3

程序实现自动生成30道四则运算题目

课堂上老师要求我们做这样一个题目,题目要求是自动生成30道四则运算题目,要求除整数加减乘除外,还有真分数加减乘除.刚开始听到这个题目一头雾水,有点复杂,但仔细拆分这个题目不难发现,这个题目可以简化成三个小问题,分别是随机数自动生成两个数,自动生成符号,还有输出结果.对于随机数自动生成两个数可以简化为随机数生成整数,随机数生成真分数,生成真分数可以简化到随机数生成分子和分母.对于自动生成符号,也可以简化为随机数生成1,2,3,4,分别代表+,—,*,/,输出结果可以用一个for循化,实现输出30道

两道拓扑排序的问题

多久没写东西了啊.... 两道拓扑排序Liv.1的题....方法是一样的~~ <拓扑排序·二> 题目:http://hihocoder.com/contest/hiho81/problem/1 一个电脑网路,单向边,如果存在边u->v,那么u的病毒会感染到v. 要点,不存在环!那么如果u的入度=0的话,那么u中的病毒数不会再变化. 想到拓扑排序.不断删去入度为0的点.每次删去节点u,如果存在u->v,那么病毒数 num[v] += num[u].问题解决. (用queue实现拓扑排

病毒的侵扰和再侵扰两道AC自动机的应用

HDU2896 病毒的侵扰 http://vjudge.net/problem/viewProblem.action?id=16404 题目大意: 记录每个病毒的编号,并给出一些网站的源码,分别输出网站及其对应编号中所含病毒的编号,没有就不输出 最后输出有病毒网站的个数 这道题需要注意的是这个所有ASCII码均会用到,所以我之前傻傻地写str[i]-'a'还不知为什么会错简直苦逼~~ 这里直接用ch[now][str[i]]找到对应位置即可 因为要记录编号,为了防止重复访问,我对query中进行