南阳理工学院软件月赛

装背包

有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

floyd处理后计算最短天数

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎轩栀海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值