zoukankan      html  css  js  c++  java
  • NYOJ 136 等式 (哈希)

    题目链接

    描述

    有以下等式:a1x13+a2x23+a3x33+a4x43+a5*x53=0

    x1,x2,x3,x4,x5都就在区间[-50,50]之间的整数,且x1,x2,x3,x4,x5都不等于0.

    问:给定a1,a2,a3,a4,a5的情况下,x1,x2,x3,x4,x5共有多少种可能的取值?

    • 输入
      第一行输入一个整数T(T<=10)表示测试数据的组数。每组测试数据都只有一行,是5个整数,分表表示a1,a2,a3,a4,a5。(a1,a2,a3,a4,a5都在区间[-50,50]之间)
    • 输出
      对于每组数据输出一行,表示x1,x2,x3,x4,x5可能的取值种数
    • 样例输入
      1
      37 29 41 43 47
    • 样例输出
      654

    分析:

    刚开始以为是母函数,然后发现思路上不同,暴力的话不用考虑肯定会超时。然后就想到用哈希来解决这个问题。我们可以先把前两项或者前三项放入到哈希表中,然后在哈希表中找后三项或者后两项。以放前两项为例。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<stack>
    #include<string.h>
    #include<stdlib.h>
    #include<queue>
    #include<algorithm>
    #include<set>
    #include<map>
    #include <cstdio>
    #define mod 10007
    using namespace std;
    int a1,a2,a3,a4,a5;
    struct Node
    {
        int key;//关键字
        long long int cnt;//个数
        int next;//下一个值得下标
    } node[100005];//结构体
    
    
    
    int Hash1[10007];//哈希函数
    int Sum;
    
    int QuYu(unsigned int num)
    {
        return num%mod;
    }
    
    void Insert(int num)
    {
        int index=QuYu(num);
        for(int i=Hash1[index]; i!=-1; i=node[i].next)///首先是在哈希函数中找到这个链表的头节点,然后往下找,看看有没有与num相同的值
            if(node[i].key==num)///如果有的话
            {
                node[i].cnt++;///个数加
                return ;
            }
            
        ///哈希函数中,采用链表法来解决哈希冲突,而对于有冲突的数据,应用头插法插入到链表中
        node[Sum].key=num;///相当于这个数字是第一次出现
        node[Sum].cnt=1;
        node[Sum].next=Hash1[index];
        Hash1[index]=Sum;
        Sum++;
    }
    long long int Find(int num)
    {
        int index=QuYu(num);
        for(int i=Hash1[index]; i!=-1; i=node[i].next)///首先是在哈希函数中找到这个链表的头节点,然后往下找,看看有没有与num相同的值
        {
            if(node[i].key==num)///有的话就返回数量
                return node[i].cnt;
        }
        return 0;///没找到就以为着哈希表中没有这个数,返回个数为0
    }
    
    void build()///首先构造哈希函数
    {
        Sum=0;
        for(int i=0; i<mod; i++)
            Hash1[i]=-1;
        for(int i=-50; i<=50; i++)
            for(int j=-50; j<=50; j++)
            {
                if(i&&j)
                    Insert(a1*i*i*i+a2*j*j*j);///把对应的前两项的值放入
            }
    }
    
    void solve()
    {
        long long int ans=0;
        for(int i=-50; i<=50; i++)
            for(int j=-50; j<=50; j++)
                for(int k=-50; k<=50; k++)
                {
                    if(i&&j&&k)
                        ans+=Find(-a3*i*i*i-a4*j*j*j-a5*k*k*k);
                }
        printf("%lld
    ",ans);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5);
            build();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    获取字符串出现的次数
    手机号码正则表达式验证
    DOM: EVENT FLOW
    AsyncCallback 异步回调委托
    高德地图
    我的json
    Arrow function restore
    constructor&object 的联系与对比
    for each/in/of的解释and example
    program发展史及以后预测
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6731554.html
Copyright © 2011-2022 走看看