1. 程式人生 > >#10167. 「一本通 5.3 練習 2」不要 62

#10167. 「一本通 5.3 練習 2」不要 62

杭州人稱那些傻乎乎粘嗒嗒的人為 626262(音:laoer)。

杭州交通管理局經常會擴充一些的士車牌照,新近出來一個好訊息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大眾。

不吉利的數字為所有含有 444 或 626262 的號碼。例如:62315,73418,8891462315,73418,8891462315,73418,88914 都屬於不吉利號碼。但是,611526115261152 雖然含有 666 和 222,但不是 626262 連號,所以不屬於不吉利數字之列。

你的任務是,對於每次給出的一個牌照區間號,推斷出交管局今後又要實際上給多少輛新的士車上牌照了。

【輸入格式】

輸入的都是整數對 n,mn,mn,m,如果遇到都是 000 的整數對,則輸入結束。

【輸出格式】

對於每個整數對,輸出一個不含有不吉利數字的統計個數,該數值佔一行位置。

【樣例輸入】

1 100
0 0

【樣例輸出】

80

【資料範圍與提示】

對於全部資料,0<n≤m<1070\lt n\le m\lt 10^70<n≤m<10​7​​。

思路:我真的不想說了

就一句話:一位一位模擬

不懂的話就直接看程式碼吧,我解釋的很清楚了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
ll f[2100][2100];//f[i][j]表示以i為最高位的j位數的吉利數字有多少個 
ll x,y;
ll a[2100],len;//len表示當前這個數的最高位,a陣列是記錄數位的 
void dfs()
{
	for(int i=0;i<=9;i++) if(i!=4) f[i][1]=1;//一位數的情況,只要不為4,這種情況就是成立的 
	for(int i=2;i<=10;i++)//數位的迴圈(2^31是十位數) 
	{ 
		for(int j=0;j<=9;j++) if(j!=4)//從當前的最高位開始迴圈
		{ 
			for(int k=0;k<=9;k++) if(k!=4 && (j!=6 || k!=2))//次高位,只要不是4或者最高位和次高位聯合起來不是62就可以 
			{
				f[j][i]+=f[k][i-1];//當前的以j為最高位的i位數 繼承的是 以次高位的k為最高位的i-1位數的狀態(當前是i位,前一個就是i-1) 
			}
		}
	}
}
ll solve(int t)//尋找合適的數 //t表示當前要計算的是 //用函式表示是為了程式碼的簡潔,不用x計算一次,y又計算一次 
{
	ll sum=0;//記錄答案 
	len=0;//數位最開始要初始化(注意:不能為了方便在上面將len初始化,這樣每一次計算就會歸0) 
	if(t==0) return 1;
	while(t>0)
	{
		a[++len]=t%10;
		t/=10;
	}//分離數位儲存在a數組裡面 
	a[len+1]=0;//a陣列也要初始化,不用擔心會計算不了,因為a[++len]會覆蓋 
	for(int i=len;i>=1;i--)//從當前這個數的最高位開始迴圈,i表示的是位數 
	{
		for(int j=0;j<a[i];j++)//保證不會超出範圍 //j就是第i位數的數字 
		//比如說,如果是4321,a[i]=4,那麼j就表示 0~3999,如果=a[i]就是0~4999 就超出了要求的數的範圍了 
		{
			if(j!=4 && (a[i+1]!=6 || j!=2)) sum+=f[j][i];
			//當前這一位a[i]也可以表示為j不是4就可以繼續判斷,
			//而且,當前這一位的上一位的數字不能為6,而且當前這一位a[i]也可以表示為j的不是2就不能湊出62,就是成立的 
		}
		if(a[i]==4 || (a[i]==2 && a[i+1]==6)) break;
		//如果迴圈到這個數的某一位是4,或者當前的某一位和前面一位是62,就退出,因為不符合條件 
		if(i==1) sum++;//如果一直迴圈到最後一位,就是一位數仍然成立,就記錄這一種答案 
	}
	return sum;
}
int main()
{
	dfs();
	while(scanf("%lld%lld",&x,&y)!=EOF)
	{
		if(x==0 && y==0) break;//如果x==0 並且 y==0,就沒有成立的,不輸出答案,直接退出 
		printf("%lld\n",solve(y)-solve(x-1));
	}
	return 0;
}

就是這樣,多組資料,一位一位判斷