搜尋專練(二)
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;
}