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;
}