H - Equations HDU - 1496(暴力for循环、折半枚举、应用hash优化折半枚举)

分析

  • 题意
  1. a ∗ x 1 2 + b ∗ x 2 2 + c ∗ x 3 2 + d ∗ x 4 2 = 0 a*x1^2 + b*x2 ^ 2+c*x3 ^ 2+d*x4^2=0 ax12+bx22+cx32+dx42=0,
  2. 给我们一个等式其中 a、b、 c、 d 均为已知变量,其中 x 1 x 2 x 3 x 4 x1 x2 x3 x4 x1x2x3x4均为未知变量,他们的范围均在[-100,-1]与[1,100]之间,让我们找出使方程成立的解的方案数量
  • 思路一
  1. 我们用 用三重for循环枚举,前三个变量的值,在[1,100]范围内,最后确定第4个变量的值是否合理,合理 ans ++, 最后 由于每个变量的范围都是在[-100,-1]与[1,100]之间, 所以 在最后 答案ans*= 16

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define db double
#define Pir pair
#define m_p make_pair
#define INF 0x3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
#define for_(i, s, e) for(int i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(int i = (ll)(e); i >= (ll)(s); i --)
#define sc scanf
#define pr printf
#define sd(a) scanf("%d", &a)
#define ss(a) scanf("%s", a)
using namespace std;

const int mxn = 1e4 + 10;
int ba[mxn];
int ar[mxn];
int pw[mxn];
void init()
{
    for_(i, 1, 100) pw[i * i] = 1;
}

int main()
{
    /* fre(); */
    int a, b, c, d;
    init();
    while(~ sc("%d %d %d %d", &a, &b, &c, &d))
    {
        if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0))
        {
            pr("0\n"); continue;
        }

        int ans = 0;
        for_(i, 1, 100)
            for_(j, 1, 100)
                for_(k, 1, 100)
                {
                    int sm = -(a * i * i + b * j * j + c * k * k);
                    if(sm % d == 0 && sm / d >= 1 && sm / d <= 10000 && pw[sm / d])
                        ans ++;
                }
            
        pr("%d\n", ans * 16);
    }


    return 0;
}




  • 思路二
    我们用用两层for循环枚举 前两个变量的的值,得出 a ∗ x 1 2 + b ∗ x 2 2 a*x1^2 + b*x2 ^ 2 ax12+bx22的值,并把 − ( a ∗ x 1 2 + b ∗ x 2 2 ) -(a*x1^2 + b*x2 ^ 2) (ax12+bx22) 插入到 map容器中,之后我们在枚举后两个变量,得到值 c ∗ x 3 2 + d ∗ x 4 2 c*x3 ^ 2+d*x4^2 cx32+dx42,检测这个值是否在map容器中出现过,如果出现了ans++

代码



  • 思路三
    这个思路,与思路二相同,只不过 存储的时的数据结构变成了 链式前向星 ,查询的时候也 改成了链式前向星的查询

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define db double
#define Pir pair
#define m_p make_pair
#define INF 0x3f3f3f3f
#define esp 1e-7
#define mod (ll)(1 << (15 - 1))
#define for_(i, s, e) for(int i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(int i = (ll)(e); i >= (ll)(s); i --)
#define sc scanf
#define pr printf
#define sd(a) scanf("%d", &a)
#define ss(a) scanf("%s", a)
using namespace std;

const int mxn = 1e6;
int head[mxn];
struct Node
{
    int val;
    int num;
    int nxt;
} node[mxn];
int tot = 0;

int Hash(int x)
{
    return (x % mod + mod) % mod;
}

void Add(int x)
{
    int H = Hash(x);
    for(int i = head[H]; ~ i; i = node[i].nxt)
    {
        if(node[i].val == x)
        {
            node[i].num ++;
            return;
        }
    }
    node[++ tot] = (Node){ x, 1, head[H] }; head[H] = tot;
}
int Search(int x)
{
    int H = Hash(x);
    for(int i = head[H]; ~ i; i = node[i].nxt)
    {
        if(node[i].val == x)
        {
            return node[i].num;
        }
    }
    return 0;
}



int main()
{
    /* fre(); */
    int a, b, c, d;
    while(~ sc("%d %d %d %d", &a, &b, &c, &d))
    {
        if((a > 0 && b > 0 && c > 0 && d > 0)||(a < 0 && b < 0 && c < 0 && d < 0))
        {
            printf("0\n");
            continue;
        }

        memset(head, -1, sizeof(head)); 
        tot = 0;
        int ans = 0;

        for_(i, 1, 100)
            for_(j, 1, 100)
            {
               Add(-(a * i * i + b * j * j)); 
            }

        for_(i, 1, 100)
            for_(j, 1, 100)
            {
                ans += Search(c * i * i + d * j * j);
            }
        pr("%d\n", ans * 16);
    }

    return 0;
}

你可能感兴趣的:(#Hash)