1. 程式人生 > >2013藍橋杯c語言c組第9題

2013藍橋杯c語言c組第9題

標題:帶分數

100 可以表示為帶分數的形式:100 = 3 + 69258 / 714
還可以表示為:100 = 82 + 3546 / 197
注意特徵:帶分數中,數字1~9分別出現且只出現一次(不包含0)。
類似這樣的帶分數,100 有 11 種表示法。

題目要求:
從標準輸入讀入一個正整數N (N<1000*1000)
程式輸出該數字用數碼1~9不重複不遺漏地組成帶分數表示的全部種數。
注意:不要求輸出每個表示,只統計有多少表示法!

例如:
使用者輸入:
100
程式輸出:
11

再例如:
使用者輸入:
105
程式輸出:
6

資源約定:
峰值記憶體消耗 < 64M
CPU消耗 < 3000ms

請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入…” 的多餘內容。

所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。

注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include , 不能通過工程設定而省略常用標頭檔案。

提交時,注意選擇所期望的編譯器型別。

#include<iostream>
#include<math.h>
using namespace std;



/*
 2013藍橋杯預賽 c語言c組倒數第二題 帶分數
 
 全排列 暴力搜尋 感覺超時了 

*/ 


#define N 10
int count=0;//全域性變數 計數

int   input=0;//輸入的數 





//檢查等式右邊第一個數是否合法 
int check(int i,int visit[]){
	int b[N]={0};
	while(i!=0){
		if(b[i%10]==0)
			b[i%10]=1;
		else{
			return 0;
		}
		i=i/10;
			
		
	}
	
	for(int i=1;i<10;i++){
		visit[i]=b[i];
	}
	return 1;
}

//交換 
int swap(int *a,int *b){
	int temp=*a;
	*a=*b;
	*b=temp;
	
}

//全排列 

//最後一個引數為等式右邊第一個數
int par(int arry[],int k,int l,int he){
	
	if(l==k)
	{		
			//排列之後分割2個集合進行判斷 
			for(int i=0;i<=l-2;i++){
			int j=0;
			int k=pow(10,i);
			int sum=0;
		
			while(k){
				sum=sum+arry[j++]*k;
				k/=10;
			}
			int j1=i+1;
			int k1=pow(10,l-i-2);
			int sum2=0;
			while(k1){
				sum2=sum2+arry[j1++]*k1;
				k1/=10;
			}
			if((input-he)*sum2==sum)
				count++;
		}
			
	
	}
	else{
			for(int i=k;i<l;i++){
				swap(arry[i],arry[k]);
				par(arry,k+1,l,he);
				swap(arry[i],arry[k]);
				
				
			
			}
		
	}
	
	
	
	
}



int main(){
	
	
	cin>>input;
	
	
 	for(int i=1;i<input;i++){ //篩選等式右邊的數 
	
		int visit[N]={0};//陣列下標標記沒有用過的數 
		
		if(check(i,visit)!=0&&i%10!=0)  //篩選無重複的和符合條件的數 
		{
		
		
		   	int arry[10];//儲存沒有用過的數一共有k個 
			int k=0; 
			for(int j=1;j<N;j++){
			  	if(visit[j]==0)
				arry[k++]=j;
			}
			
			
			par(arry,0,k,i);
		
			
			
		}
		
		
	}
	cout<<count;
	
	
	
	
}