判断一个数是否是完全平法数
对于给定一个整数N
定义一个整型数M
int M = sqrt(N);
然后判断
if(M*M == N)
则N是平方数;
else
N不是平方数;
第一遍代码结果和标准答案不一样,当时没有考虑到等差数列里的number拆解成两个平方数时,这两个平方根不能大于给定的M值——在处理(5,7)时我的程序给出了1,24的结果,实际上这个数列里有用到9^2 + 4^2,而9 大于 7 是不能使用的,在加入了平方根root小于M值的判定条件后,我的第二版程序在 test 6 时超时了……fuck,下面是第二版程序
/*
ID: wangxin12
PROG: ariprog
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
vector<int> ans;
int N, M;
bool isBiSquare(int number, int maxNum) ;
int main() {
ifstream fin("ariprog.in");
ofstream fout("ariprog.out");
fin>>N;
fin>>M;
int maxNum = M * M * 2;
int maxDiff = maxNum / (N - 1);
int start = 0; //the first number in progression
int diff = 1; //the difference between adjencent numbers
int n = 0;
for( diff = 1; diff <= maxDiff; diff++ ) {
for(start = 0; start <= (maxNum - (N - 1) * diff); start++) {
//for every unique start & diff pair, check if all numbers in this progression are bisquares
bool flag = true;
for(n = 0; n < N; n++) {
//check
if(!isBiSquare(start + n * diff, M)) {
flag = false;
break;
}
}
//if check passed, output the answer
if(flag) {
//fout<<start<<" "<<diff<<endl;
ans.push_back(start);
ans.push_back(diff);
}
}
}
//cout<<isBiSquare(97,98);
if(ans.empty()) {
fout<<"NONE"<<endl;
} else {
for(int k = 0; k < ans.size(); k += 2) {
fout<<ans[k]<<" "<<ans[k + 1]<<endl;
}
}
fin.close();
fout.close();
return 0;
}
bool isBiSquare(int number, int M) {
bool biFlag = false;
for(int i = 0; i * i <= number /2; i++) {
int rest = number - i * i;
int root =(int) sqrt((double)rest);
if(root <= M && root * root == rest) {
biFlag = true;
break;
}
}
return biFlag;
}
正在琢磨怎么优化……
在http://blog.youkuaiyun.com/vinsonou/article/details/7054669 上看到了优化方向——“上网看了一下别人的思路,原来是应该强搜双平方数,而不是强搜a b,双平方数最多有250*250*2 = 125000,可以接受,在双平方数中先强搜确定a,再根据a+nb<2*m*m确定b的强搜范围,对每个a b判断所有的序列是否属于双平方数。ACM虽然接触了一下,但仅仅限于选修课上。个人感觉每道题都不太会,看到题目只会强搜,深一点的算法题就不会了。但听了一位师兄说,只要坚持搞ACM一个月,一定会有感觉的。正在努力当中。。。”
于是下一版代码通过测试,主要修改了 bool isBiSquare()函数,将所有双平方数存入数组,再进行直接查找,比较方便。
/*
ID: wangxin12
PROG: ariprog
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
vector<int> ans;
int N, M;
bool biSquare[125000+10] = { false };
bool isBiSquare(int number) ;
int main() {
ifstream fin("in.txt");
ofstream fout("out.txt");
fin>>N;
fin>>M;
//initial biSquare array to speed up
for(int t1 = 0; t1 <= M; t1++)
for(int t2 = 0; t2 <= M; t2++) {
int t = t1 * t1 + t2 * t2;
if(biSquare[t] == false) biSquare[t] = true;
}
int maxNum = M * M * 2;
int maxDiff = maxNum / (N - 1);
int start = 0; //the first number in progression
int diff = 1; //the difference between adjencent numbers
int n = 0;
for( diff = 1; diff <= maxDiff; diff++ ) {
for(start = 0; start <= (maxNum - (N - 1) * diff); start++) {
//for every unique start & diff pair, check if all numbers in this progression are bisquares
bool flag = true;
for(n = 0; n < N; n++) {
//check
if(!isBiSquare(start + n * diff)) {
flag = false;
break;
}
}
//if check passed, output the answer
if(flag) {
ans.push_back(start);
ans.push_back(diff);
//fout<<start<<" "<<diff<<endl;
}
}
}
//cout<<isBiSquare(97,98);
if(ans.empty()) {
fout<<"NONE"<<endl;
} else {
for(int k = 0; k < ans.size(); k += 2) {
fout<<ans[k]<<" "<<ans[k + 1]<<endl;
}
}
fin.close();
fout.close();
return 0;
}
bool isBiSquare(int number) {
return biSquare[number];
}
/*
bool isBiSquare(int number, int M) {
bool biFlag = false;
for(int i = 0; i * i <= number /2; i++) {
int rest = number - i * i;
int root =(int) sqrt((double)rest);
if(root <= M && root * root == rest) {
biFlag = true;
break;
}
}
return biFlag;
}
*/