閱讀620 返回首頁    go 阿裏雲 go 技術社區[雲棲]


poj 1207 The 3n + 1 problem

當我看到題目的時候我就感覺到這是一道徹徹底底的水題,因為很像A+B的作風。。。

但是看完題目我心裏想了想:應該沒有那麼水吧,可能還是要優化的,暴力可能會TLE。。。

但是我暴力過了以後我這樣想:。。。。。。。


下麵摘抄了一點文字說明:

大致題意:

根據給定的算法,可以計算一個整數的循環數

現在給定一個區間,計算這個區間的所有數的循環數,把最大的循環數輸出

PS:輸出的是整數A的循環數,而不是輸出整數A

解題思路:

注意的隻有一點:

輸入的兩個區間端點不一定是從小到大輸入的,因此要先對這兩個數排一下序。



【純暴力】AC的代碼:


#include<stdio.h>

int Process(int i)
{
	int count=1;
	while(i!=1)
	{
		if(i%2)
			i=3*i+1;
		else
			i/=2;
		count++;
	}
	return count;
}

//這題居然可以暴力過。。。我不解釋
int main()
{
	int a,b;
	while(scanf("%d%d",&a,&b)!=EOF)
	{
		int x=a<b?a:b;
		int y=a>b?a:b;
		int Max=0;

		for(int i=x;i<=y;i++)
		{
			int temp=Process(i);
			if(Max<temp)
				Max=temp;
		}

		printf("%d %d %d\n",a,b,Max);
	}

	return 0;
}



寫寫自己”不暴力“的思路:

要維護兩個集合

1. 每個數當然最好有一個自己的數組專門存循環節的長度,因為很可能區間有重疊。。。

2. 另外一個集合 【鏈表】就是把 循環序列 都存起來,因為循環節很可能就是重複的,比如知道 4 的長度是 3 ,那 8/2 以後就是 4 ,就不用算了,長度就是3+1=4;這樣就要每次檢查一次,如果有就結束循環,否則如果沒有就 插入那個序列,這就涉及  搜索 ,當然最好用  二分。。。


這樣就不算水了。。。


最後我並不是用這個解法。。。我是維護了一個Trace數組,相當於維護路徑。。。之後再處理路徑上的值的循環節。。。在電腦上對了,但是一直Runtime Error。。。改了數組上下界無數次也不行。。。後來直接改成 int 數組的極大值,AC了


附代碼:

#include <stdio.h>

//自動初始化為0
int Num[99999999];
int Trace[99999999];

void RecordTrace(int count)
{
	int i;
	for(i=count;i>=1;i--)
	{
		if(Num[Trace[i]]!=0)
			continue;

		else
			Num[Trace[i]]=i;
	}
}



int Process(int pos)
{
	int count=1;
	Trace[1]=pos;
	while(pos!=1)
	{
		
		if(pos%2)
		{
			pos=3*pos+1;
			if(Num[pos]!=0)
			{
				count+=Num[pos];
				RecordTrace(count);
				return count;
			}

			else
			{
				count++;
				Trace[count]=pos;
			}
		}

		else
		{
			pos/=2;
			if(Num[pos]!=0)
			{
				count+=Num[pos];
				RecordTrace(count);
				return count;
			}

			else
			{
				count++;
				Trace[count]=pos;
			}
		}
	}
	
	return count;
}



int main()
{
	int a,b;
	while(scanf("%d%d",&a,&b)!=EOF)
	{
		int x=a<b?a:b;
		int y=a>b?a:b;
		int max=-1;
		
		int i,tmp;
		for(i=x;i<=y;i++)
		{
			if(Num[i]!=0)
			{
				if(Num[i]>max)
					max=Num[i];
			}
				
			else
			{
				tmp=Process(i);
				if(tmp>max)
					max=tmp;
			}
		}

		printf("%d %d %d\n",a,b,max);
	}
	
	return 0;
}




另:附上一個不水的解法

POJ 1207 HDOJ/HDU 1032 3n+1數鏈問題 絕對不水的解法


最後更新:2017-04-03 14:53:50

  上一篇:go 【轉載】第一個GNURadio應用程序心得
  下一篇:go FTPHelper-封裝FTP的相關操作