Section 1.4-ariprog

5 篇文章 0 订阅
4 篇文章 0 订阅
本文介绍了作者在解决编程竞赛问题时,遇到的效率问题以及改进策略。通过构建布尔数组,作者在"lBisequares"和"exam_ariprog"两个问题上显著提升了程序运行速度。
摘要由CSDN通过智能技术生成

My first answer's problem: take too much time

/*
ID: penglin3
PROG: ariprog
LANG: C++11
*/
#include<algorithm>//sort 所在头文件,sort是C++的快排函数比qsort好用
#include <iostream>
#include <fstream>
#include<vector>
using namespace std;
struct arithprog
{
	int a;
	int b;
};
bool  arithmetic_progressions(const vector<long> &bisequares,int N,int first,int second);//检验bisequares是否含有等差数列first、second为下标
bool lessmark(const arithprog &s1, const arithprog &s2)
{
	if (s1.b != s2.b)return s1.b < s2.b;
	else return s1.a < s2.a;
}
int main() {
	ifstream fin("ariprog.in");
	ofstream fout("ariprog.out");	

	int N, M;
	fin >> N >> M;

	//build datalake and sort;
	vector<long> lake{};
	for (int q = 0; q <= M; ++q)
		for (int p = q; p <= M; ++p)
			lake.push_back(p*p + q*q);
	sort(lake.begin(), lake.end());

	//remove repeat nums and clear  lake;
	vector<long> bisequares{lake[0]};
	for (auto &lake_iterator : lake)
	{
		if (lake_iterator != bisequares[bisequares.size() - 1])
			bisequares.push_back(lake_iterator);
	}
	lake.clear();

	//examing from begin to end
	int i, j;
	arithprog basket{};
	vector<arithprog> answer = {};
	for (i = 0; i != bisequares.size() - N + 1; ++i)
	{
		for (j = i + 1; j != bisequares.size() - N + 2; ++j)
			{
				if (bisequares[i] + (bisequares[j] - bisequares[i])*(N - 1) > 2 * M * M)break;
				if (arithmetic_progressions(bisequares, N, i, j))
				{
					basket.a = bisequares[i];
					basket.b = bisequares[j] - bisequares[i];
					answer.push_back(basket);
				}
			}
	}
	sort(answer.begin(), answer.end(), lessmark);

	if (answer.empty())fout << "NONE" << endl;
	else {
		for (auto itanswer : answer)
			fout << itanswer.a << " " << itanswer.b << endl;
	}

	fin.close();
	fout.close();
	return 0;
}
bool  arithmetic_progressions(const vector<long> &bisequares,int N, int first, int second)
{
	long deduct = bisequares[second] - bisequares[first];
	N -= 2;
	for (int i = second + 1; i != bisequares.size() && N > 0; ++i)
	{
		if (bisequares[i] - bisequares[second] == deduct)
		{
			second = i; N -= 1;
		}
		else if (bisequares[i] - bisequares[second] > deduct) break;
	}
	if (N > 0)return false;
	else return true;
}


The better way is build a bool array.

It has two benefits in "lBisequares" and "exam_ariprog".

/*
ID: penglin3
PROG: ariprog
LANG: C++11
*/
#include<algorithm>//sort 所在头文件,sort是C++的快排函数比qsort好用
#include <iostream>
#include <fstream>
#include<vector>
using namespace std;
struct ariprog {
	int a;
	int b;
};
bool lessmark(const ariprog &s1, const ariprog &s2);
//排序方式函数
bool exam_ariprog(const bool series[], const int& N, const long& a0, const long& b);
//数列中是否存在 a0开头、步长为b、含有N个数的等差数列(N包括a0);
int main() {
	ifstream fin("ariprog.in");
	ofstream fout("ariprog.out");

	int N, M;
	fin >> N >> M;
	
	bool bBisequares[125001] = {};//default values are false;
	for (int q = 0; q <= M; ++q)
		for (int p = q; p <= M; ++p) {
			bBisequares[p*p + q*q] = true;
		}

	vector<long> lBisequares = {};
	int max = M * M * 2;
	for (int i = 0; i <= max; ++i) {
		if (bBisequares[i]) {
			lBisequares.push_back(i);
			//fout << lBisequares[lBisequares.size() - 1] << endl;
		} 

	}
	long deduct;
	ariprog basket;
	vector<ariprog> answer;
	//fout << exam_ariprog(lBisequares, N - 2, , 588);
	for (int i = 0; i != lBisequares.size() - N + 1; ++i){
		int a0 = lBisequares[i];
		for (int j = i + 1; j != lBisequares.size() - N + 2; ++j){
			deduct = lBisequares[j] - a0;
			if (a0 + deduct*(N - 1) > max) break;
			else if (exam_ariprog(bBisequares, N - 1, a0 + deduct , deduct)){
				basket.a = a0; basket.b = deduct;
				answer.push_back(basket);
			}
		}
	}

	if (answer.empty())fout << "NONE" << endl;
	else {
		sort(answer.begin(), answer.end(), lessmark);
		for (auto &itanswer : answer)
			fout << itanswer.a << " " << itanswer.b << endl;
	}
	fin.close();
	fout.close();
	return 0;
}

bool lessmark(const ariprog &s1, const ariprog &s2)
{
	if(s1.b!=s2.b)return s1.b < s2.b;
	else return s1.a < s2.a;
}

bool exam_ariprog(const bool series[],const int& N,const long& a0, const long& b)
{			//数列中是否存在 a0开头、步长为b、含有N个数的等差数列(N包括a0);
	long a = a0;
	for (int i = 2; i <= N; ++i) {//a0必属于该数列,所以该数列直接从第二个数算起
		a += b;
		if (!series[a])return false;
	}
	return true;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值