哈希(hdu 1280 && 1425 && 1264 && 1496 && 2522 && 2600)

1280:题目:点击打开链接

这题的本意应该是要我们写哈希吗……总之哈希和排序都能过,开始因为格式输出错误了,所以错了好几次………………

哈希快速的原因是因为不用排序。

#include <stdio.h>
#include <string.h>

int hash[10010];
int a[3100];

int main (void)
{
	int n, m;
	while(scanf("%d %d", &n, &m) != EOF)
	{
		memset(hash, 0, sizeof(hash));
		int i, j;
		for(i = 0; i < n; i++)
			scanf("%d", &a[i]);
		for(i = 0; i < n; i++)
		{
			for(j = i + 1; j < n; j++)
			{
				hash[a[i] + a[j]]++;
			}
		}
		for(i = 10001; i >= 0; i--)
		{
			if(m == 0)
				break;
			if(hash[i])
			{
				while(hash[i] && m != 0) 
				{
					if(m == 1)
						printf("%d", i);
					else
						printf("%d ", i);	
					m --;
					hash[i]--;
				}
			}
		}
		printf("\n");
	}
	return 0;
}

排序方法:
#include <stdio.h>
#include <stdlib.h>

int a[3100];
int sum[5000000];

int cmp(const void* a, const void* b)
{
    return (*(int *)b - *(int *)a);
}

int main (void)
{
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        int i, j, k = 0;    
        for(i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        for(i = 0; i < n; i++)
        {
            for(j = i + 1; j < n; j++)
                sum[k ++] = a[i] + a[j];
        }
        qsort(sum, k, sizeof(sum[0]), cmp);
        for(i = 0; i < m - 1; i++)
        {
            printf("%d ", sum[i]);
        }
        printf("%d", sum[m - 1]);
        printf("\n");
    }
    return 0;
}

1425题目: 点击打开链接

这题和上面的题方法是一样的,比较基础的哈希

#include <stdio.h>
#include <string.h>

bool hash[1000000];

int main (void)
{
	int n, m;
	while(scanf("%d %d", &n, &m) != EOF)
	{
		int i, a;
		for(i = 0; i < n; i++)
		{
			scanf("%d", &a);
			hash[a + 500000] = 1;
		}
		for(i = 1000000; i >= 0; i--)
		{
			if(m == 0)
				break;
			if(hash[i])
			{
				if(m == 1)
					printf("%d", i - 500000);
				else
					printf("%d ", i - 500000);
				m--;
			}
		}
		printf("\n");
	}
	return 0;
}

1264题目:点击打开链接


题目的大意就是给你几个矩形,让你计算这些矩形所总共包含的1*1的小矩形有多少个,当然重复的只能算一个。用哈希表做,还是比较简单的,效率也很高。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int s[110][110];

void swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

int main (void)
{
	int a, b, c, d;
	int sum = 0;
	while(1)
	{
		scanf("%d %d %d %d", &a, &b, &c, &d);
		if(a == -1 && b == -1 && c == -1 && d == -1)
		{
			printf("%d\n", sum);
			sum = 0;
			memset(s, 0, sizeof(s));
		}
		if(a == -2 && b  == -2 && c == -2 && d == -2)
		{
			printf("%d\n", sum);
			break;
		}
		int i, j;
		if(a > c)
			swap(a, c);
		if(b > d)
			swap(b, d);
		for(i = a; i < c; i++)
		{
			for(j = b; j < d; j++)
			{
				if(s[i][j] == 0)
				{
					s[i][j] = 1;
					sum ++;
				}
			}
		}
	}
	return 0;
}

1496题目:点击打开链接

我觉得这题用红哈希用的挺巧妙的,我刚开始数组开太大,超内存。

#include <stdio.h>
#include <string.h>

int hash[5000010];

int main (void)
{
	int a, b, c, d;
	while(scanf("%d %d %d %d", &a, &b, &c, &d) != EOF)
	{
		if(a > 0 && b > 0 && c > 0 && d > 0 || a < 0 && b < 0 && c < 0 && d < 0)
		{
			printf("0\n");
			continue;
		}
		memset(hash, 0, sizeof(hash));
		int i, j;
		for(i = -100; i <= 100; i++)
		{
			if(i == 0)
				continue;
			for(j = -100; j <= 100; j++)
			{
				if(j == 0)
					continue;
				hash[a * i * i + b * j * j + 2500000]++;
			}
		}
		int sum = 0, temp;
		for(i = -100; i <= 100; i++)
		{
			if(i == 0)
				continue;
			for(j = -100; j <= 100; j++)
			{
				if(j == 0)
					continue;
				temp = (-c) * i * i + (-d) * j * j + 2500000;
				sum += hash[temp];
			}
		}
		printf("%d\n", sum);
	}
	return 0;
}

2522题目:点击打开链接

这题用到哈希的地方应该就是记录商和余数的时候。

#include <stdio.h>
#include <string.h>
int num[100000], n;//记录商 
bool vis[100000];//记录余数在之间的计算中是否出现过 
int yu[100000], m;//记录余数 
//判断循环节是否开始,就是判断此次计算所得的余数在之前的计算中是否出现过 

int main (void)
{
	double a, b;
	int i, ncase, f;
	scanf("%d", &ncase);
	while(ncase --)
	{
		f = 0;
		scanf("%lf", &b);
		if(b < 0)
		{
			printf("-");
			b = -b;
		}
		printf("%d.", (int)(1 / b));
		a = 1 - (int)(1 / b) * b;//a为余数 
		vis[(int)a] = 1;
		yu[m ++] = a;
		
		while(1)
		{
			a *= 10;
			int temp = (int)a / b;
			a = a - (int)(a / b) * b;
			if(vis[(int)a] == 0)
			{//余数a在之前的计算中没出现过 
				vis[(int)a] = 1;
				yu[m ++] = a;
				num[n ++] = temp;
				
				if(a == 0)
				{//如果余数是0了说明不存在循环节,并且可以除尽 
				 //那么就将之前所计算的数输出即可 
					for(i = 0; i < n; i++)
						printf("%d", num[i]);
					printf("\n");
					break;
				}
			}
			else
			{//余数a出现过说明循环开始,那么开始输出 
				num[n] = temp;	
				for(i = 0; i <= n; i ++)
				{
					printf("%d", num[i]);
				}
				printf("\n");
				break;
			}
		}
		memset(vis, 0, sizeof(vis));
		memset(num, 0, sizeof(num));
		memset(yu, 0, sizeof(yu));
		n = 0;
		m = 0;
	}
	return 0;
}


2600题目:点击打开链接

题目大意就是给你一个时间段,然后再给你这个时间段中的战争发生的时间和战争的名称,输出在这个时间段内没有战争的最大的年份。也是个比较简单的哈希。

#include <stdio.h>
#include <string.h>

bool war[12000100];

int main (void)
{
	int n;
	while(scanf("%d", &n) != EOF)
	{
		memset(war, 0, sizeof(war));
		int p, q, i, j, a, b;
		char s[20];
		scanf("%d %d", &p, &q);
		for(i = 0; i < n; i++)
		{
			scanf("%d %d", &a, &b);
			gets(s);
			for(j = a; j <= b; j++)
			{
				war[j + 6000000] = 1; 
			}
		}
		int f = 0;
		for(i = q + 6000000; i >= p + 6000000; i--)
		{
			if(war[i] == 0)
			{
				printf("%d\n", i - 6000000);
				f = 1;
				break;
			}
		}
		if(f == 0)
		{
			printf("Badly!\n");
		}
	}
	return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值