2008 ACM-ICPC SWERC

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=328

还是一如既往的菜,过了4题:A,C,D,I


A题:在两点之间找一条路,是的最长的边最短,那么所有的边一定在最小生成树上

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
#define MAXN 3005
#define inf 1000000000
int n;
int mat[3005][3005];
int pre[3005];
int query[3005];
int prim(){
       int mini[MAXN],ret=0;
       int v[MAXN],i,j,k;
       for (i=0;i<n;i++)
              mini[i]=inf,v[i]=0,pre[i]=-1;
       for (mini[j=0]=0;j<n;j++){
              for (k=-1,i=0;i<n;i++)
                    if (!v[i]&&(k==-1||mini[i]<mini[k]))
                            k=i;
              for (v[k]=1,ret+=mini[k],i=0;i<n;i++)
                     if (!v[i]&&mat[k][i]<mini[i])
                            mini[i]=mat[pre[i]=k][i];
       }
       return ret;
}

int main()
{
    int T,t1,m,i,j,x,y,l,Q;
    scanf("%d",&T);
    for(t1=1;t1<=T;t1++)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            mat[i][j]=1e6+5;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&l);
            if(l<mat[x-1][y-1])mat[x-1][y-1]=l;
            if(l<mat[y-1][x-1])mat[y-1][x-1]=l;
        }
        prim();
        printf("Case %d\n",t1);
        /*for(i=0;i<n;i++)
            printf("%d ",pre[i]);
        printf("\n");*/
        scanf("%d",&Q);
        while(Q--)
        {
            memset(query,0,sizeof(query));
            scanf("%d%d",&x,&y);
            x--;
            y--;
            if(x==y)
            {
                printf("0\n");
                continue;
            }
			query[x]=max(1,query[x]);
            while(pre[x]!=-1)
            {
                query[pre[x]]=max(query[x],mat[x][pre[x]]);
                x=pre[x];
                //printf("%d %d %d\n",x,pre[x],mat[x][pre[x]]);
            }
            
            if(query[y]!=0)
            {
                printf("%d\n",query[y]);
                continue;
            }
            while(pre[y]!=-1)
            {
                if(query[pre[y]]!=0)
                {
                    printf("%d\n",max(query[pre[y]],max(query[y],mat[y][pre[y]])));
                    break;
                }
                query[pre[y]]=max(query[y],mat[y][pre[y]]);
                y=pre[y];
            }
            if(pre[y]==-1)printf("%d\n",query[y]);

        }
        printf("\n");
    }
    return 0;
}


C题:

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int maxx = 105;
struct kuai
{
	double x,y;	
	int tot;
}k[15][15];
int n;

int main()
{
	long long cnt = 0;
	while(~scanf("%d",&n) && n)
	{
		cnt = 0;
		double nx,ny;
		double ans = 0;
		memset(k,0,sizeof(k));
		for(int i = 0; i < n; i++)
		{
			scanf("%lf%lf",&nx,&ny);
			int x = nx,y = ny;
			k[x][y].x += nx;
			k[x][y].y += ny;
			k[x][y].tot++;
		}
		for(int i = 0; i < 10; i++)
		{
			for(int j = 0; j < 10; j++)
			{
				double nx = k[i][j].x;
				double ny = k[i][j].y;
				int tot = k[i][j].tot;
				if(tot)
				for(int i1 = i+1; i1 < 10; i1++)
				{
					for(int j1 = j+1; j1 < 10; j1++)
					{
						int tot1 = k[i1][j1].tot;
						if(tot1)
						{
							double nx1 = k[i1][j1].x;
							double ny1 = k[i1][j1].y;
							ans += nx1 * tot - nx * tot1;
							ans += ny1 * tot - ny * tot1;
							cnt += 1ll* tot1 * tot;
						}
					}
				}
			}
		}
		ans /= cnt;
		printf("%.8lf\n",ans);
	}
	return 0;
}


D题:Floyd算法求两两最短距离,然后预处理概率,通过递推算出概率即可

#include <bits/stdc++.h>
using namespace std;
#define ll long long
char s[105][105];
int a[105][105];
double e[50];
double p[105][3005];
int t,n,r,q;

int main()
{
	scanf("%d",&t);
	int step=0;
	while (t--)
	{
		step++;
		memset(e,0,sizeof(e));
		memset(p,0,sizeof(p));
		scanf("%d%d",&n,&r);
		for (int i=0;i<n;i++)
		{
			scanf("%s",s[i]);
		}
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=n;j++)
			{
				if (s[i-1][j-1]=='Y') a[i][j]=1;
				else a[i][j]=10000;
			}
		}
		for (int k=1;k<=n;k++)
			for (int i=1;i<=n;i++)
				for (int j=1;j<=n;j++)
					a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
		for (int i=1;i<=r;i++)
		{
			e[i]=1.0/r;
			p[1][i]=1.0/r;
		}
		for (int i=1;i<n;i++)
		{
			for (int j=i;j<=i*r;j++)
			{
				for (int k=1;k<=r;k++)
				{
					p[i+1][j+k]+=p[i][j]*e[k];
				}
			}
		}
		printf("Case %d\n",step);
		scanf("%d",&q);
		while (q--)
		{
			int x,y,m;
			scanf("%d%d%d",&x,&y,&m);
			int len=a[x][y];
			if (m>=len*r) printf("1.000000\n");
			else
			{
				double ans=0;
				for (int i=len;i<=m;i++)
				{
					ans+=p[len][i];
				}
				printf("%.6f\n",ans);
			}	
		}
		printf("\n");
	}
	return 0;
}


I题:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int t,n;
ll x[1005],y[1005];

int main()
{
	scanf("%d",&t);
	while (t--)
	{
		memset(x,0,sizeof(x));
		scanf("%d",&n);
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=9;j++)
			{
				ll c;
				scanf("%lld",&c);
				x[i]+=c;
			}
			scanf("%lld",&y[i]);
		}
		ll m=1;
		int can=1;
		int can2=0;
		ll g;
		for (int i=1;i<=n;i++)
		{
			if (x[i]<y[i])
			{
				can=0;
				break;
			}
			if (x[i]==y[i]) m=max(m,x[i]);
			else if (x[i]>y[i])
			{
				if (can2==0) g=x[i]-y[i];
				else g=__gcd(g,x[i]-y[i]);
				m=max(m,y[i]);
				can2=1;
			}
		}
		if (can==1 && can2==1)
		{
			if (g>m) printf("%lld\n",g);
			else printf("impossible\n");
		}
		else printf("impossible\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/njupt_lyy/article/details/81039803