装背包
有N种物品各一个,问是否能够凑成Mkg装到背包中。
Input
第一行一个整数T(T<=1000)测试数据组数,每组第一行为(1<N<=1000),M(1<m<=1000)两个正整数,第二行N个整数代表N种物品的质量Gi(小于1000)。
Output
可以凑成输出“Y”,否则输出“N”
Sample Input
2 3 5 1 2 3 3 7 1 2 3
Sample Output
Y N
类似于 01 背包
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[1100],dp[110000];
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--){
int flag=0;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
for(int j=m;j>=a[i];j--){
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
if(dp[j]==m){
flag=1;
break;
}
}
}
if(flag) printf("Y\n");
else printf("N\n");
}
return 0;
}
考古
考古专家发现了一个葬着多人的大墓穴,可是骨头杂乱无序堆在一起,考古学家现确定了某些对骨头应该是同一个人的,问这个洞穴中,最多葬了多少个人(木有骨头的肯定不用算了)。
Input
多组输入数据(少于100),每组第一行两个正整数N(小于1000表示骨头个数),M(之后M行会告诉你哪两个骨头是一个人的),当N为0时,输入结束,该用例不被处理。
Output
每组输出一个数,表示这里最多埋葬了多少人。
Sample Input
4 3 1 2 2 3 1 3 0
Sample Output
2
并查集
#include<stdio.h>
int f[1100];
int finx(int x)
{
if(x==f[x]) return x;
else return finx(f[x]);
}
int main()
{
int n,m;
int x,y,tx,ty;
while(~scanf("%d%d",&n,&m)){
if(n==0) break;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
tx=finx(x);
ty=finx(y);
if(tx!=ty)
f[tx]=ty;
}
int num=0;
for(int i=1;i<=n;i++){
if(f[i]==i) num++;
}
printf("%d\n",num);
}
return 0;
}
洞的编号
有N(N<1000)个洞围成一个圈编号(1-N),从1号洞开始走N次,分别走1^9步,2^9步,3^9步······N^9步,问此时所在的洞的编号。
Input
多组输入数据(不超过100组),每行一个正整数N。
Output
洞的编号
Sample Input
1 2 3 4
Sample Output
1 2 1 1
#include<stdio.h>
#include<string.h>
int main()
{
int n,m,k;
while(~scanf("%d",&n)){
m=0;
for(int i=1;i<=n;i++){
k=1;
for(int j=1;j<=9;j++) k=(k*i)%n;
m=(m+k)%n;
}
printf("%d\n",m+1);
}
return 0;
}
七龙珠
Input
第一行一个整数T(少于5组)表示测试数据组数,每组数据第一行 N(2<=N<=300个城镇),M(0<M<100),
之后有n+m行,前n行每行n个整数,第K行的L个数表示第K镇到第L镇的距离,之后m行每行6个整数表示取珠城市顺序(第一个整数为当前位置) 。(均在int范围内)
Output
每组数据m行,每行一个整数,最少需要的天数。
Sample Input
1 6 1 0 2 2 2 2 5 2 0 3 3 3 4 2 3 0 4 5 4 2 3 4 0 1 3 2 3 5 1 0 6 5 4 4 3 6 0 1 2 3 4 5 6
Sample Output
14
Hint
样例为1-2-3-4-5-4-6
#include<stdio.h>
#include<string.h>
int Map[500][500];
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--){
memset(Map,0,sizeof(Map));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&Map[i][j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(Map[j][k] > Map[j][i]+Map[i][k])
Map[j][k]=Map[j][i]+Map[i][k];
}
}
}
int a,d,sum;
while(m--){
sum=0;
scanf("%d",&a);
for(int i=1;i<6;i++){
scanf("%d",&d);
sum+=Map[a][d];
a=d;
}
printf("%d\n",sum);
}
}
return 0;
}
飞船汇合
一支分散的飞船舰队,需要汇合到主舰,但是这种飞船在太空中飞行的耗油与质量没有关系,只与发动机打开的时间有关系,为了节省油量,指挥官通知,汇合途中,多台飞船可以串成串飞行,这样只需启动一台发动机,由于安全因素飞船只能走某些航线(某飞船到某飞船的航线)。指挥发现这样的移动方案可能有多种,但最短汇合时间相同,指挥官想考察你是否知道在总耗油最小的情况下,最短多久汇合完毕。
Input
T(T<10)组数据每组第一行有一个整数N(飞船个数<=300),之后第一行是其他飞船到主舰的时间,再有n行,每行n个数Aij表示Ai到Aj的时间。(均在int范围内)
Output
每组数据输出总耗油最小的情况下,总耗油量与最短汇合时间。
Sample Input
1 5 5 7 4 3 6 0 2 1 6 3 2 0 3 1 4 1 3 0 4 5 6 1 4 0 2 3 4 5 2 0
Sample Output
9 7
逆向引水工程,DFS再求母舰到其他舰的最远距离(这个可以借助第一问的最小生成树求解)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int Map[310][310],p[310],pre[310];
int n;
struct node {
int x,y;
int len;
};
node d[1000];
int cmp(node a,node b){
return a.len<b.len;
}
int find(int x)
{
int a=x;
while(a!=p[a]){
a=p[a];
}
int b=x,kk;
while(b!=a){
kk=p[b];
p[b]=a;
b=kk;
}
return a;
}
bool join(int xx,int yy)
{
int fx=find(xx);
int fy=find(yy);
if(fx!=fy){
p[fy]=fx;
return true;
}
return false;
}
//最短时间
int maxn=0;
void dfs(int x,int step)
{
for(int i=1;i<=n;i++){
if(Map[x][i] && !pre[i]){
pre[i]=1;
dfs(i,step+Map[x][i]);
}
}
if(maxn<step) maxn=step;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(Map,0,sizeof(Map));
memset(pre,0,sizeof(pre));
for(int i=0;i<=n;i++) p[i]=i;
int k,m=0;
for(int i=0;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&k);
if(i<j){ //存一半的边
d[m].x=i;
d[m].y=j;
d[m].len=k;
m++;
}
}
}
//经典的最小生成树问题
sort(d,d+m,cmp);
int sum=0,cnt=0;
for(int i=0;cnt<n;i++){
if(join(d[i].x,d[i].y)){
++cnt;
sum+=d[i].len;
Map[d[i].x][d[i].y]=d[i].len;
Map[d[i].y][d[i].x]=d[i].len;
}
}
pre[0]=1;
dfs(0,0);
printf("%d %d\n",sum,maxn);
}
return 0;
}