目录
一、四位完全平方数
首先完全平方数的定义:一个数如果是另一个整数的完全平方,那么就称这个数为完全平方数
法一、枚举后拆分判断法
扫描二维码关注公众号,回复: 17229788 查看本文章首先完全平方数四位数的范围确定:
31*31=961,32*32=1024 ,故最小因数从32开始
100*100=10000,但它不符合题意,故最大因数从99开始
这里采用枚举出所有可能的四位数的因数,然后因数相乘再判断这个数的前两位是否相同,后两位是否相同
注:要学会四位数的拆分,代码如下
#include<iostream>
using namespace std;
int main()
{
int i;
for (i = 32; i <= 99; ++i)
{//先枚举出四位数
int t = i * i;
int a = t / 1000;//千位
int b = t / 100 % 10;//百位
int c = t % 100 / 10;//十位
int d = t % 10;//个位
if (a == b && c == d)
{
cout << t << endl;
}
}
return 0;
}
法二、先判断再枚举
对于一个四位数,前两位、后两位相等的情况,比如1122,4422,9988,前两位、后两位一定是11的倍数,但要注意最高位一定不为0,故高位从1开始,由此利用枚举写出代码
#include<iostream>
using namespace std;
int main()
{
for (int i = 1; i <= 9; ++i)
{//一个四位数最高位不能为0,故从1开始
for (int j = 0; j <= 9; ++j)
{
//t就是前两位、后两位相等的一个四位数
int t = i * 1100 + j * 11;
for (int k = 32; k <= 99; ++k)
{
if (t == k * k)
{
cout << t << endl;
break;
}
}
}
}
return 0;
}
二、验证子串
思路:
首先先输入的子串还是主串不确定,那我们就假设s1为主串,s2为子串就好了,然后再正常用BF算法求解,下标从0开始
1、解释下while中两个判断条件,为什么要同时判断主串和子串是否走到头?
①、主串走到头的情况:比如主串一直没找到与子串相匹配的位置,主串会走到头,但此时子串还没到头,故不匹配。
②、 子串走到头的情况:在找的过程中子串匹配成功主串,那子串就会走到头,故匹配成功。故只要有一个条件不满足,就跳出while循环判断
2、关于i = i - j + 1,若下标从0开始则i = i - j + 1,若从1开始就是i = i - j + 2
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1, s2;
cin >> s1 >> s2;
//使s1是主串,s2是子串
if (s1.size() < s2.size())
{//若小于则说明s2才是主串
//那就使s1和s2交换,让s1做主串
string tmp = s1;
s1 = s2;
s2 = tmp;
}
int Lens1 = s1.size();
int Lens2 = s2.size();
int i = 0, j = 0;//利用下标指示位置
while (i < Lens1 && j < Lens2)
{
if (s1[i] == s2[j])
{//对应字符相等,则后移
++i;
++j;
}
else
{
i = i - j + 1;//主串的i返回到原位置的下一位置
j = 0;//子串的j回到开头
}
}
if (j == Lens2)
{//子串都走完了,说明它是主串的子串
cout << s2 << " is substring of " << s1 << endl;
}
else
{
cout << "No substring" << endl;
}
return 0;
}
三、珠心算测验
思路:
利用桶计算,比如现有数据1,2,3,4,每个数据对应都有一个桶(用来存放球),对于两个不同的数相加得到另一个数的就加一个球,1+2=3,故3的桶加个球,1+3=4,故4的桶加个球,那么这个球转换到代码中就是++运算,无论多少个球,只要有一个球就说明这个数据是其他不同数的加和,至于你放了几次球是无所谓的,很好的解决了一个数重复出现的问题
#include<iostream>
using namespace std;
//a来存数的个数,利用t的下标来存两个数的加和
int a[105];
int t[20005];//是105而不是100是为了防止数溢出
int main()
{
int n = 0;
int cnt = 0;//统计次数
cin >> n;
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
{
t[a[i] + a[j]]++;//a[i]+a[j]就是相加来的数
}
}
for (int k = 0; k < n; ++k)
{
//若对于数组中的一个数,桶中对应位置有"球",则++cnt
if (t[a[k]] > 0)
++cnt;
}
cout << cnt << endl;
return 0;
}
四、 火柴棒等式
思路:
用暴力穷举法的唯一难点在于枚举的最大范围是什么?为了提高效率,我们找到的这个最大范围越精准是越好的。
除去+和=,火柴棒最多剩20根,因为1所用火柴棒最少,故用20根火柴最多可枚举到1111,1111+1=1112,除去+和=用了21根>20了,所以每个数最大应该到1111,但实际上运行完发现,最多到711就结束了,0+711=711,共用了24根火柴(不过代码中用1111即可)
#include<iostream>
using namespace std;
int a[10] = { 6,2,5,5,4,5,6,3,7,6 };//统计0~9每个数字所需火柴棒数
int c(int x)
{
if (x == 0)//若x为0,直接返回他所需火柴棒数
return 6;
int sum = 0;//统计x所需的火柴棒总数
while (x > 0)
{
sum += a[x % 10];
x /= 10;
}
return sum;
}
int main()
{
int n = 0, cnt = 0;
cin >> n;
n -= 4;//除去+和=还剩下数字能用的火柴棒个数
for (int i = 0; i <= 1111; ++i)
{
for (int j = 0; j <= 1111; ++j)
{
if (c(i) + c(j) + c(i + j) == n)
++cnt;
}
}
cout << cnt << endl;
return 0;
}