HDU1264、1280、1425、1496、1800(简单哈希练习)

Counting Squares

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2439    Accepted Submission(s): 1184


Problem Description
Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in the range 0 to 100. For example, the line
5 8 7 10
specifies the rectangle who's corners are(5,8),(7,8),(7,10),(5,10).
If drawn on graph paper, that rectangle would cover four squares. Your job is to count the number of unit(i.e.,1*1) squares that are covered by any one of the rectangles given as input. Any square covered by more than one rectangle should only be counted once.
 

Input
The input format is a series of lines, each containing 4 integers. Four -1's are used to separate problems, and four -2's are used to end the last problem. Otherwise, the numbers are the x-ycoordinates of two points that are opposite corners of a rectangle.
 

Output
Your output should be the number of squares covered by each set of rectangles. Each number should be printed on a separate line.
 

Sample Input
 
  
5 8 7 10 6 9 7 8 6 8 8 11 -1 -1 -1 -1 0 0 100 100 50 75 12 90 39 42 57 73 -2 -2 -2 -2
 

Sample Output
 
  
8 10000
 

题目大意:以-1截止为一组数据,每组数据有多对点,每行2个点,表示矩形的左上角点坐标和右下角坐标,求每组矩形覆盖的面积。输入-2时结束。

思路:哈希运用?感觉像是小技巧,数据很小,可直接设地图,然后遍历,若覆盖便更新数据。

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
int p[105][105];
using namespace std;
int main()
{
    int a,b,c,d,i,j,s=0,t;
    while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
    {
        if(a==-1)
        {
            memset(p,0,sizeof(p));
            printf("%d\n",s);
            s=0;
            continue;
        }
        if(a==-2)
        {
            printf("%d\n",s);
            break;
        }
        if(a>c) { t=a,a=c,c=t;}
        if(b>d) { t=b,b=d,d=t;}
        for(i=a+1;i<=c;i++)
        {
            for(j=b+1;j<=d;j++)
            {
                if(p[i][j]==0)
                {
                    p[i][j]=1;
                    s++;
                }
            }
        }
    }
    return 0;
} 

前m大的数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 23194    Accepted Submission(s): 7839


Problem Description
还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。
给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000)并按从大到小的顺序排列。
 

Input
输入可能包含多组数据,其中每组数据包括两行:
第一行两个数N和M,
第二行N个数,表示该序列。

 

Output
对于输入的每组数据,输出M个数,表示结果。输出应当按照从大到小的顺序排列。
 

Sample Input
 
  
4 4 1 2 3 4 4 5 5 3 6 4
 

Sample Output
 
  
7 6 5 5 11 10 9 9 8
 

思路:哈希?。。。数据这么小,暴力吧。

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<set>
#include<math.h>
int p[3005],p1[10005]={0};
using namespace std;
int main()
{
    int n,m,i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        k=0;
        memset(p,0,sizeof(p));
        memset(p1,0,sizeof(p1));
        for(i=0;i<n;i++)
        {
            scanf("%d",&p[i]);
        }
        for(i=0;i<n;i++)
        {
            for(j=i+1;j<n;j++)
            {
                p1[p[i]+p[j]]++;
            }
        }
        int fag=0;
        for(i=10000;i>=0;i--)
        {
            if(p1[i]!=0&&fag==0)
            {
                while(p1[i]!=0)
                {
                    printf("%d",i);
                    p1[i]--;k++;
                    if(k==m) { fag=1;break;}
                    printf(" ");
                }
            }
        }
        printf("\n");
    }
    return 0;
} 

sort

Time Limit: 6000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 58157    Accepted Submission(s): 16098


Problem Description
给你n个整数,请按从大到小的顺序输出其中前m大的数。
 

Input
每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
 

Output
对每组测试数据按从大到小的顺序输出前m大的数。
 

Sample Input
 
  
5 3 3 -35 92 213 -644
 

Sample Output
 
  
213 92 3

思路:数据10^6,暴力?好像不行吧...........但是就是暴力能过....大概是sort O(n*logn),还是数据弱?

代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
int s[2000000];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n,m,i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
             scanf("%d",&s[i]);
        sort(s,s+n,cmp);
        for(i=0;i<m;i++)
        {
            if(i==m-1)
             printf("%d\n",s[i]);
            else
              printf("%d ",s[i]);
        }
    }
    return 0;
}

Equations

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9403    Accepted Submission(s): 3909


Problem Description
Consider equations having the following form:

a*x1^2+b*x2^2+c*x3^2+d*x4^2=0
a, b, c, d are integers from the interval [-50,50] and any of them cannot be 0.

It is consider a solution a system ( x1,x2,x3,x4 ) that verifies the equation, xi is an integer from [-100,100] and xi != 0, any i ∈{1,2,3,4}.

Determine how many solutions satisfy the given equation.
 

Input
The input consists of several test cases. Each test case consists of a single line containing the 4 coefficients a, b, c, d, separated by one or more blanks.
End of file.
 

Output
For each test case, output a single line containing the number of the solutions.
 

Sample Input
 
  
1 2 3 -4 1 1 1 1
 

Sample Output
 
  
39088 0
 

题目大意:给出一个四元方程,四个未知数的数据范围为正负100,多组数据输入系数a,b,c,d;输出每组的解个数。

思路:如果考虑暴力,四重for循环,遍历-100到100;10^2^4=10^8,差不多接触到底线了,抱着侥幸的心理暴力,虽然限时3s,妥妥的超时。然后考虑优化的问题,个人认为,哈希是一种优化的方法,着重用于处理数据,优化代码速率。我使用的是一种比较普通的方法。对半折开,一半存可选择项,一半直接匹配,算是使用了哈希的思想,借化解冲突的方法减少匹配。

代码如下:

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
#define MS 1000005
int s[2000005];
int main() 
{
    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;
        }
        for(int i=0;i<MS*2;i++) s[i]=0; 
        for(int i=-100;i<=100;i++) 
        {
            if(i!=0)
                for(int j=-100;j<=100;j++) 
                {
                    if(j!=0)
                    {
                        int x=a*i*i+b*j*j;
                        s[x+MS]++;//该情况可匹配的个数 
                    }
                }
        }
        int sum=0;
        for(int i=-100;i<=100;i++) 
        {
            if(i!=0)
                for(int j=-100;j<=100;j++) 
                {
                    if(j!=0) 
                    {
                        int x=c*i*i+d*j*j;
                        sum+=s[MS-x];//能该情况能完成匹配的数累加 
                    }
                }
        }
        printf("%d\n",sum);
    }
    return 0;
}

Flying to the Mars

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23521    Accepted Submission(s): 7524


Problem Description

In the year 8888, the Earth is ruled by the PPF Empire . As the population growing , PPF needs to find more land for the newborns . Finally , PPF decides to attack Kscinow who ruling the Mars . Here the problem comes! How can the soldiers reach the Mars ? PPF convokes his soldiers and asks for their suggestions . “Rush … ” one soldier answers. “Shut up ! Do I have to remind you that there isn’t any road to the Mars from here!” PPF replies. “Fly !” another answers. PPF smiles :“Clever guy ! Although we haven’t got wings , I can buy some magic broomsticks from HARRY POTTER to help you .” Now , it’s time to learn to fly on a broomstick ! we assume that one soldier has one level number indicating his degree. The soldier who has a higher level could teach the lower , that is to say the former’s level > the latter’s . But the lower can’t teach the higher. One soldier can have only one teacher at most , certainly , having no teacher is also legal. Similarly one soldier can have only one student at most while having no student is also possible. Teacher can teach his student on the same broomstick .Certainly , all the soldier must have practiced on the broomstick before they fly to the Mars! Magic broomstick is expensive !So , can you help PPF to calculate the minimum number of the broomstick needed .
For example :
There are 5 soldiers (A B C D E)with level numbers : 2 4 5 6 4;
One method :
C could teach B; B could teach A; So , A B C are eligible to study on the same broomstick.
D could teach E;So D E are eligible to study on the same broomstick;
Using this method , we need 2 broomsticks.
Another method:
D could teach A; So A D are eligible to study on the same broomstick.
C could teach B; So B C are eligible to study on the same broomstick.
E with no teacher or student are eligible to study on one broomstick.
Using the method ,we need 3 broomsticks.
……

After checking up all possible method, we found that 2 is the minimum number of broomsticks needed.
 

Input
Input file contains multiple test cases.
In a test case,the first line contains a single positive number N indicating the number of soldiers.(0<=N<=3000)
Next N lines :There is only one nonnegative integer on each line , indicating the level number for each soldier.( less than 30 digits);
 

Output
For each case, output the minimum number of broomsticks on a single line.
 

Sample Input
 
  
4 10 20 30 04 5 2 3 4 3 4
 

Sample Output
 
  
1 2
 

题目大意:士兵飞火星,需要学骑魔法扫把,每个士兵学习能力有高低,高的能够教导低的共用一把扫把。可以没有老师和学生,求所需的最少扫把数。

思路:求最多重复数,因为最多出现的与最高、最低都只需一把扫把,再使用map容器和迭代器。(看了下网上的题解,解题方法非常多,字典树,贪心.....不懂,暂时没练到那些专题)。

代码如下:

#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
int main()
{
    int n,v,maxs;
    while(scanf("%d",&n)!=EOF)
    {
        maxs=-155;
        map<int,int>m;//第一个为关键字,第二个为关键字的值
        while(n--)
        {
            scanf("%d",&v);
            m[v]++;
        }
        for(map<int,int>::iterator it=m.begin();it!=m.end();it++)
        {
            if(it->second>maxs)
            {
                maxs=it->second;
            }
        }
        cout<<maxs<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/pleasantly1/article/details/81006062