搜索专练(二)

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84953568

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;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84953568