1. 程式人生 > >列舉法、窮舉法

列舉法、窮舉法

首先是一道暴力列舉的例題,然後陳述列舉法的定義和暴力指的是什麼意思;

題目描述

有一天,mirror給了kyoma一個數x,讓kyoma找到一個正整數y>=2,使得y-x的絕對值最小。
但是kyoma覺得這樣做太簡單了,於是她反問mirror,要求在滿足上一個條件的同時,這個y中的每個質因數均恰好出現2次。
mirror感到很困難,你能夠幫幫她嗎?

輸入

第一行輸入一個整數T(1<=T<=50)
每組資料有一行,一個整數x(1<=x<=10^18)

輸出

對於每組資料,輸出一行y-x的最小絕對值

樣例輸入

5
1112
4290
8716
9957
9095

樣例輸出

23
65
67
244
70
一、題目資訊: 1.絕對值——>y可能比x小,可能比x大,但是滿足條件的y一定是在x周圍的——>while(x--)  while(x++) 2.質因數(把喵喵坑的好苦啊)——>給定一個數n,n的因數是質數,則稱該數為質因數 3.y中的每個質因數均恰好出現兩次——>y一定是一個平方數——>y一定是一個合數——>合數可以表示成若干個質數相乘的形式           ↓      從2開始驗證,在sqrt(y)中只能出現一次,出現兩次以上,該數一定不符合條件,且通過驗證的數一定是質數 二、程式碼實現: typedef long long ll;
while(t--)    (我學了一些小改變)
#include 
#include 
using namespace std;
typedef long long ll;
bool judge(ll y)
{
	bool re=true;
	if(sqrt(y)!=(ll)sqrt(y))
	{
		return false;
	}
	ll s=sqrt(y);
	for(ll i=2;s!=1;i++)
	{
		if(s%i==0)
		{
			s/=i;
			if(s%i==0)
			{
				return false;
			}	
		}
	}
	return re;
}
int main()
{
	int T;
	ll x;
	ll y;
	cin>>T;
	ll minus,mm,min;
	while(T--)
	{
		cin>>x;
		y=x;
		while(y)
		{
			minus=x;
			if(judge(y))
			{
				minus=abs(x-y);
				break;
			}
			y--;
			
		}
		y=x+1;
		while(1)
		{
			mm=x;
			if(judge(y))
			{
				mm=abs(x-y);
				break;
			}
			y++;
			
		}
		min=mm

(宣告:完全是個人理解,不是課本上的官方定義,有理解不對的地方,求求你告訴我) 暴力法:從題意出發,不運用什麼技巧,按照題目的條件或者是數學公式,順序解題。 (在暴力的過程中可能會發現簡單解題的方法,例如:含有多個變數的等式,可能可以減少變數,從而可能減少迴圈) 列舉法與窮舉法:根據題目給出的限制條件,挨個資料進行檢驗,最終找出符合條件的答案。(在範圍內,挨個判斷挨個找) 列舉法的缺點:資料量大的話會導致時間崩潰 列舉的一般結構:while迴圈 列舉解題的基本思路: 1.確定列舉物件,列舉範圍和判斷條件 2.列舉可能的解,驗證 經典問題:百錢買百雞 有一個人有一百塊錢,打算買一百隻雞。到市場一看,大雞三塊錢一隻,小雞一塊錢三隻,不大不小的雞兩塊錢一隻。現在,請你編一程式,幫他計劃一下,怎麼樣買法,才能剛好用一百塊錢買一百隻雞?