1. 程式人生 > >搜尋專練(二)

搜尋專練(二)

p1172 健康的荷斯坦奶牛

題目

描述 Description
農民園園以擁有世界上最健康的奶牛為驕傲。但她知道每種飼料中所包含的牛所需的最低的維他命量是多少。請你幫助園園餵養她的牛,以保持它們的健康,使餵給牛的飼料的種數最少。

給出牛所需的最低的維他命量,輸出餵給牛需要哪些種類的飼料,且所需的飼料劑量最少。
由於她太懶,所以這個問題就交給你了。。
維他命量以整數表示,每種飼料最多隻能對牛使用一次,她會讓你通過此題所以資料保證存在解。

輸入格式 Input Format
第1行:一個整數V(1<=V<=25),表示需要的維他命的種類數。
第2行:V個整數(1<=每個數<=1000),表示牛每天需要的維他命的最小量。
第3行:一個整數G(1<=G<=15),表示可用來喂牛的飼料的種數。
下面G行,第i行表示編號為i飼料包含的各種維他命的量的多少。

輸出格式 Output Format
輸出檔案只有一行,包括

牛必需的最小的飼料種數P

後面有P個數,表示所選擇的飼料編號(按從小到大排列)。

為了讓你進行思考,如果有多個解,輸出飼料序號最小的(即字典序最小)。 注意輸出順序

樣例輸入 Sample Input

4
100 200 300 400
3
50 50 50 50
200 300 200 300
900 150 389 399

樣例輸出 Sample Output

2 1 3

時間限制 Time Limitation
1s
註釋 Hint
1s
來源 Source
usaco 2.1.4

程式碼

#include<bits/stdc++.h>
using namespace std; int n, m, v[26], g[16][26], num[26]; bool eat[16]; int ans = 30, cnt = 0; inline int read() { int f=1,num=0; char ch=getchar(); while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9') { num=(num<<1)+(num<<3)+ch-'0'; ch=
getchar(); } return num*f; } bool eatup() {//吃夠了? for (int i = 1;i <= n;i ++) if (v[i] > 0) return false; return true; } void dfs(int k) { if ( eatup() ) {//吃夠,判斷,更新答案 if (cnt < ans) { ans = cnt; int pos = 1, i = 1; while (pos <= m) { if ( eat[pos] ) num[i++] = pos; pos ++; } } return ; } if (k > m) return ; for (int i = 1;i <= n;i ++)//吃 v[i] -= g[k][i]; eat[k] = 1; cnt ++; dfs(k+1); eat[k] = 0;//不吃 for (int i = 1;i <= n;i ++) v[i] += g[k][i]; cnt --; dfs(k+1); } int main() { n = read(); for (int i = 1;i <= n;i ++) v[i] = read(); m = read(); for (int i = 1;i <= m;i ++) for (int j = 1;j <= n;j ++) g[i][j] = read(); dfs(1); cout<<ans<<' '; for (int i = 1;i <= ans;i ++) cout<<num[i]<<' '; return 0; }

p1179 8皇后問題

題目

描述 Description
在一個n×n的棋盤上放置n個國際象棋中的皇后,要求所有的皇后之間都不形成攻擊。請你給出所有可能的排布方案數。
輸入格式 Input Format
一個整數n
輸出格式 Output Format
一個整數表示方案數
樣例輸入 Sample Input

4
樣例輸出 Sample Output

2
時間限制 Time Limitation
1s
註釋 Hint
n<=8
來源 Source
經典問題

程式碼

#include<bits/stdc++.h>
#include<cstring>
using namespace std;
int n,sum=0;
int pos[20];
bool column[20],cross1[150],cross2[150];
void dfs(int row)
{
	if (row==n) 
	{
		sum++;
		return;
	}
	for (int i=0;i<+n;i++)
		if (!(column[i]||cross1[row-i+n]||cross2[row+i]))
		{
			column[i]=cross1[row-i+n]=cross2[row+i]=true;
			pos[row]=i;
			dfs(row+1);
			column[i]=cross1[row-i+n]=cross2[row+i]=false;
		}
}
int main()
{
	cin>>n;
	memset(column,0,sizeof(column));
	memset(cross1,0,sizeof(cross1));
	memset(cross2,0,sizeof(cross2));
	dfs(0);
	cout<<sum<<endl;
	return 0;
}

p1181 質數肋骨

題目

描述 Description
農民約翰的母牛總是生產出最好的肋骨。你能通過農民約翰和美國農業部標記在每根肋骨上的數字認出它們。
農民約翰確定他賣給買方的是真正的質數肋骨,是因為從右邊開始切下肋骨,每次還剩下的肋骨上的數字都組成一個質數,舉例來說: 7 3 3 1
全部肋骨上的數字 7331是質數;三根肋骨 733是質數;二根肋骨 73 是質數;當然,最後一根肋骨 7 也是質數。
7331 被叫做長度 4 的特殊質數。
寫一個程式對給定的肋骨的數目 N (1<=N<=8),求出所有的特殊質數。數字1不被看作一個質數。
輸入格式 Input Format
單獨的一行包含N。
輸出格式 Output Format
按順序輸出長度為 N 的特殊質數,每行一個。
樣例輸入 Sample Input

4
樣例輸出 Sample Output

2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393

時間限制 Time Limitation
1s
註釋 Hint

來源 Source
usaco 1.5.3

程式碼

#include<bits/stdc++.h>
using namespace std;
int n;
bool check(int z)//判斷z是不是質數 
{
	for (int i=2;i<=(int)sqrt(double(z));i++)
		if (z%i==0) return false;
	return true;
}
void dfs(int x,int y)
{
	if (!check(x)) return;//如果不是,直接退出 
	if (y==n) printf ("%d\n",x);//如果夠n位數字,輸出這個數字 
	else 
		for (int i=1;i<=9;i+=2)
			dfs(x*10+i,y+1);
}
int main()
{
	int a[5];
	ios::sync_with_stdio(false);
	cin>>n;
	a[1]=2; a[2]=3; a[3]=5; a[4]=7;
	for (int i=1;i<=4;i++)
		dfs(a[i],1);
	return 0;
}

p1182 因式分解

題目

描述 Description
將大於1的自然數n進行因式分解,滿足
          n=a1a2a3*…am
編一程式,對任意的自然數n(1<n<=2,000,000,000),求 n的所有形式不同的因式分解 方案總數。
如 n=12,共有8種分解方案,他們分別是:
   12=1×12
   12=6×2
   12=4×3
   12=3×4
   12=3×2×2
   12=2×6
   12=2×3×2
   12=2×2×3
輸入格式 Input Format
一個整數n
輸出格式 Output Format
一個整數m,代表不同的因式分解的方案總數。
樣例輸入 Sample Input

12
樣例輸出 Sample Output

8
時間限制 Time Limitation
1s
來源 Source
紅皮書:江蘇教材

程式碼

#include<bits/stdc++.h>
#include<algorithm>
#include<cmath>
using namespace std;
int n,cnt=0,ans=0;
int a[2000000],b[2000000];
int dfs(int x)
{
	int sum=0;
	if (x<1000000&&b[x]!=0) return b[x];
	if (x==1) return 1;
	else for (int i=1;i<=cnt;i++)
	{
		if (x%a[i]==0) sum+=dfs(x/a[i]);
		if (x/i<1) break;
	}
	if (x<=100000) b[x]=sum;
	return sum;			
}
int main()
{
	cin>>n;
	for (int i=2;i<=sqrt(1.0*n);i++)
		if (n%i==0)
		{
			a[++cnt]=i;
			a[++cnt]=n/i;
		}
	sort(a+1,a+cnt+1);
	for (int i=1;i<=cnt;i++)
		ans+=dfs(a[i]);
	cout<<ans+1<<endl;
	return 0;
}