#1372 : 平方求和

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

对于一个非负整数n,最少需要几个完全平方数,使其和为n?

输入

输入包含多组数据。对于每组数据:

第一行是n;如果n为-1,表示输入结束。(0 <= n <= 1000000001)

输出

针对每组数据,输出最少需要的完全平方数。

样例输入
3
4
5
-1
样例输出
3
1
2

思路:

拿到这个题,我第一想到的是贪心,每次减去一个最大数的平方,但是有时候这样会得不到正确的答案,比如19 ,贪心的话就是4,1,1,1.。。。正确的应该是3,3,1.。。。

然后dp,dp虽然可以得到正确的答案,但是时间复杂度高了。pass。

在想到搜索

让我们可视化一下,

原来是个搜索的题目。

如何加速?

我们应该深度优先搜索吗?

当然不是啦!因为我们求的是最少的拆解,所以应该宽度优先搜索。

宽搜的时候,用一个last和一个nlast分别记录当前行的最后一个元素,和下一行的最后一个元素。

如何再加速?

如果我们为了收敛快,似乎方向反了。

如何再加速?

我们有些节点是不是可能重复访问?建立一个hash表存一下吧。

如何再快呢?

证明题:每个正整数都可以表示为4个完全平方数的和。

什么?居然还需要数论的知识。我不知道怎么办?

没什么啊,我们刚才的宽度优先搜索已经能够保证和这个算法是一个复杂度了。

代码:

宽搜:

 #include <iostream>
#include <algorithm>
#include <queue>
using namespace std; //
int bfs(long long n)
{
queue<long long> q;
int t = ;
long long head,last=n,nlast; //last当前行最右,nlast下一行最右
q.push(n);
while (!q.empty())
{
head = q.front();
if (t == )
{
int c = ;
} if (t == )
break;
q.pop();
if (head != )
{
for (int i = sqrt(head); i > ; i--)
{
if (head - i*i == )
return t;
q.push(head-i*i); nlast = head - i*i;
} if (head == last && !q.empty())
{
t++;
last = nlast;
}
}
}
} int main()
{
long long n;
while (cin>>n)
{
if (n == -)
break;
cout<< bfs(n)<<endl; }
system("pause");
return ;
}

数论方法AC:

 #include <iostream>
#include <algorithm>
#include <queue>
using namespace std; //
bool is_sqrt(long long n)
{
int m = sqrt(n);
if (m*m == n)
return true;
else
return false;
} int solve(long long n)
{
if (is_sqrt(n))
return ;
while (n % == )
n /= ; if (n % == )
return ; for (int i = ; i*i < n; i++)
{
if (is_sqrt(n - i*i))
return ;
}
return ;
} int main()
{
long long n;
while (cin>>n)
{
if (n == -)
break;
cout<< solve(n)<<endl; }
system("pause");
return ;
}

hiho #1372:平方求 (bfs)的更多相关文章

  1. PKU 2002 Squares(二维点哈希+平方求余法+链地址法)

    题目大意:原题链接 给定平面上的N个点,求出这些点一共可以构成多少个正方形. 解题思路: 若正方形为ABCD,A坐标为(x1, y1),B坐标为(x2, y2),则很容易可以推出C和D的坐标.对于特定 ...

  2. hiho #1305 区间求差

    #1305 : 区间求差 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个区间集合 A 和 B,其中集合 A 包含 N 个区间[ A1, A2 ], [ A3,  ...

  3. (step4.2.1) hdu 1372(Knight Moves——BFS)

    解题思路:BFS 1)马的跳跃方向 在国际象棋的棋盘上,一匹马共有8个可能的跳跃方向,如图1所示,按顺时针分别记为1~8,设置一组坐标增量来描述这8个方向: 2)基本过程 设当前点(i,j),方向k, ...

  4. HDU 1372 Knight Moves(BFS)

    题目链接 Problem Description A friend of you is doing research on the Traveling Knight Problem (TKP) whe ...

  5. hiho 1613 - 墨水滴 - bfs+优先队列 *

    题目链接 小Ho有一张白纸,上面有NxN个格子.小Ho可以选择一个格子(X, Y),在上面滴一滴墨水.如果这滴墨水的颜色深度是G,那么这个格子也会被染成深度为G的格子.同时周围的格子也会被这滴墨水浸染 ...

  6. HDU5957 Query on a graph(拓扑找环,BFS序,线段树更新,分类讨论)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5957 题意:D(u,v)是节点u和节点v之间的距离,S(u,v)是一系列满足D(u,x)<=k的点 ...

  7. HAOI2018游记

    前言 很懒. 太懒了. 不仅懒得写题..连游记都懒得写.. 花点时间填一下坑吧..不过话说我去年的NOI/APIO/CTSC游记也没写.. 省选前 板子好像一早就打完了,没什么可干的. 也不愿意开新题 ...

  8. K - 迷宫问题

    /*定义一个二维数组:  int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, ...

  9. python机器学习《回归 一》

    唠嗑唠嗑 依旧是每一次随便讲两句生活小事.表示最近有点懒,可能是快要考试的原因,外加这两天都有笔试和各种面试,让心情变得没那么安静的敲代码,没那么安静的学习算法.搞得第一次和技术总监聊天的时候都不太懂 ...

随机推荐

  1. Matlab小技巧

    记录一些用Matlab的技巧. //imshow全屏 subplot(1,3,3); imshow(topSketMat); hold on; set(gcf, 'units', 'normalize ...

  2. bootstrap的学习-基础样式和排版一

    一.列表去除样式和横排排列 classs="list-unstyled","list-inline" 二.[表格].table 类指定基本样式,.table-s ...

  3. h5移动端滑动的细节

    1.获取手指滑动的长度: var hasTouch = 'ontouchstart' in window && !isTouchPad, _start:function(e){ var ...

  4. Jsp与servlet的区别 1

     Jsp与servlet的区别 2011-12-09 16:27:47 分类: Java 1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识 ...

  5. PHP数组处理函数的使用array_push(一)

    使用PHP做数据处理时会涉及到大量的数组操作,这里我就记下各种数组处理函数的使用方法,好记性不如烂笔头!! 一.array_push的使用方法:将一个或多个单元压入数组的末尾(入栈) 说明:int a ...

  6. 柱状堆积图Echarts

    Map<String,Object> map = new HashMap<String, Object>(); //图例的千人.双百 HashMap<String, St ...

  7. Struts2 action的单例与多例

    struts 2的Action是多实例的并非单例,也就是每次请求产生一个Action的对象.原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面 ...

  8. php中的正则函数主要有三个-正则匹配,正则替换

    php中变量的声明? 由于php声明变量的时候, 不支持使用 var关键字, 又不能直接写一个变量名字, 孤零零的放在那里, 所以, 在php中声明变量的方式, 同时也是给变量初始化的形式, 即: & ...

  9. C#委托全解析

    什么是委托?                                                                                       委托类似于C语 ...

  10. vmstat、top

    vmstat是一个查看虚拟内存(Virtual Memory)使用状况的工具,使用vmstat命令可以得到关于进程.内存.内存分页.堵塞IO.traps及CPU活动的信息. vmstat 最常用的有两 ...