Atcoder Beginner Contest 114 C-755

题目来源:Atcoder Beginner Contest 114 C

https://beta.atcoder.jp/contests/abc114/tasks/abc114_c

C - 755

 

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300300 points

Problem Statement

You are given an integer NN. Among the integers between 11 and NN (inclusive), how many Shichi-Go-San numbers (literally "Seven-Five-Three numbers") are there?

Here, a Shichi-Go-San number is a positive integer that satisfies the following condition:

  • When the number is written in base ten, each of the digits 75 and 3 appears at least once, and the other digits never appear.

Constraints

  • 1N<1091≤N<109
  • NN is an integer.

 

Input

Input is given from Standard Input in the following format:

NN

Output

Print the number of the Shichi-Go-San numbers between 11 and NN (inclusive).

 

Sample Input 1 Copy

Copy

575

Sample Output 1 Copy

Copy

4

There are four Shichi-Go-San numbers not greater than 575575357,375,537357,375,537 and 573573.

 

Sample Input 2 Copy

Copy

3600

Sample Output 2 Copy

Copy

13

There are 1313 Shichi-Go-San numbers not greater than 36003600: the above four numbers, 735,753,3357,3375,3537,3557,3573,3575735,753,3357,3375,3537,3557,3573,3575 and 35773577.

 

Sample Input 3 Copy

Copy

999999999

Sample Output 3 Copy

Copy

26484

 

题意为在3、5、7至少都有一个的基础中再添加3、5、7其中一个进去的组合有多少。

解题思路:用一个队列分别存储3、5、7,每次分别再后面加3或5或7再压入队列,更新队列的长度。并且没有判断新生成的组合是否要求,如果比输入的N小的话则计数,否则就结束枚举(因为枚举都是从3、5、7为头开始,尾部也是一个个插3、5、7,是从小到大的)且不会有重复。

#include
using namespace std;
int main()
{   char c[]={'3','5','7'};
	 int n;
	 cin>>n;
	 queueq;
	 q.push("3");
	 q.push("5");
	 q.push("7");
	 int on=3,nn=0,ans=0,flag=0;
	  while(1)
    {
    	for(int i=1;i<=on;i++)
    	{
    		 string t=q.front();
    		 q.pop();
    		 for(int j=0;j<3;j++)
    		 {
    		 	string tt=t+c[j];
    		
    		 	int num3=0,num5=0,num7=0;
    		 	for(int k=0;k>x;
    		 	q.push(tt);
    		 	nn++;
    		 	if(x<=n){
    		 		if((num3&&num5&&num7))
    		 		ans++;
				 }
				 else
				 {
				 	flag=1;
				 	break;
				 }
			 }
			 if(flag)break;
		}
		if(flag)break;
		on=nn;
		nn=0;
	}
	printf("%d",ans);
 } 

另一种写法是直接从三位数开始,每次分别在数的前面、尾部、中间插一个值,这种做法需要查重,而且重复的次数较多。

#include
using namespace std;
int main()
{
	 char b[4]={'3','5','7'};
	map M;
    queue q;
    q.push("357");
    q.push("375");
    q.push("537");
    q.push("573");
    q.push("735");
    q.push("753");
    int w=3,count=6,ans=6,nn=0,n;
    stringstream ss;
    cin>>n;
    if(n>=3357)
    {
    	 while(w>0)
    	 {
    	 	  int flag=0,x;
    	 	  for(int j=1;j<=count;j++)
    	 	  {
    	 	  	 string str =q.front(),str1;
    	 	  	 q.pop();
    	 	  	 for(int i=0;i<3;i++)
    	 	  	 {   
    	 	  	      for(int k=0;k<=w;k++)
    	 	  	 	 {   str1=str;
						 str1.insert(str1.begin()+k,b[i]);
    	 	  	 	 ss<>x;
    	 	  	 	  ss.clear();
    	 	  	 	  if(x<=n)
    	 	  	 	  {
    	 	  	 	  	 if(M[x]==0)
    	 	  	 	  	 {
    	 	  	 	  	 	 q.push(str1);
    	 	  	 	  	 	 ans++;
    	 	  	 	  	 	 nn++;
    	 	  	 	  	 	 M[x]=1;
							   }
						  }
						  else
						  flag=1;
						 }
    	 	  	  
    	 	  	 	 
					}	
			   }
				count=nn;
				nn=0;
				if(flag)
				break;
				else
				w++;
		 }
	}
  else if(n>=753) ans=6;
    else if(n>=735) ans=5;
    else if(n>=573) ans=4;
    else if(n>=537) ans=3;
    else if(n>=375) ans=2;
    else if(n>=357) ans=1;
    else ans=0;
    printf("%d\n",ans);
}

两道题效率对比。

你可能感兴趣的:(Atcoder Beginner Contest 114 C-755)