您的位置:首页 > 理论基础 > 计算机网络

【2015合肥网络赛】(没有补完)

2015-09-29 18:34 531 查看
HDU 5484 Monitor the Alpacas

HDU 5485 The Relationship in Club

HDU 5486 Difference of Clustering

HDU 5487 Difference of Languages

HDU 5488 Shape

HDU 5489 Removed Interval

HDU 5490 Simple Matrix

【HDU 5491 The Next】

这个题目应该是这场比赛里面最简单的,但是很烦,一不小心就会错

题意是给你三个数 D s1 s2 在比D大的是中找出最小的数,它的二进制中所包含的1的个数在s1~s2中间

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define ll __int64
ll p[40];
int vis[40],v[40];
void init()
{
    p[0]=1;
    ll ans=1;
    for(int i=1;i<=32;i++)
    {
        ans*=2;
        p[i]=ans;
    }
}
int main()
{
    init();
    int t,cas=1;
    scanf("%d",&t);
    while(t--)
    {
        ll d;
        int s1,s2;
        memset(vis,0,sizeof(vis));
        scanf("%I64d%d%d",&d,&s1,&s2);
        int sum=0,l=0;
        ll sd=0;
        for(int i=0;i<=32;i++)
        {
            if(d<p[i]) break;
            if(d&p[i]) 
            {
                vis[i]=1;
                sum++;
            }
            l++;
        }
        if(sum<s1)
        {
            int res=s1-sum;
            for(int i=0;i<l;i++)
            {
                if(vis[i]==0 && res>0)
                {
                    vis[i]=1;
                    res--;
                }
                if(vis[i]==1) sd+=p[i];
            }
        }
        else
        {
            for(int i=0;i<l;i++)
            {
                int s=sum;
                int flag=0;
                if(vis[i]==0)
                {
                    for(int j=0;j<l;j++) v[j]=vis[j];
                    flag=1;
                    v[i]=1;
                    s++;
                    int res=0;
                    for(int j=i-1;j>=0;j--)
                    {
                        if(v[j]==1) res++;
                    }
                    res=s-res;
                    if(res>s2) continue;
                    if(s1>res) res=s1-res;
                    else res=0;
                    for(int j=0;j<i;j++)
                    {
                        if(res>0)
                        {
                            v[j]=1;
                            res--;
                            continue;
                        }
                        if(res==0)
                        {
                            v[j]=0;
                        }
                    }
                    s=s1;
                }
                if(s>=s1 && s<=s2 && flag==1) 
                {
                    for(int j=0;j<32;j++) vis[j]=v[j];
                    break;
                }
                if(i==l-1) l++;
            }
            for(int i=0;i<l;i++)
            {
                if(vis[i]==1) sd+=p[i];
            }
        }
        printf("Case #%d: %I64d\n",cas++,sd);
    }
    return 0;
}


【HDU 5492 Find a path】

赛后补的第一个题目

题意是在n*m的矩阵中,找出一条路,起点是(1,1,),终点是(n,m),找出的路要找出以下公式的最小值,Ai表示矩阵上的点的值,Aavg是这条路上点的平均值(N+M−1)∑N+M−1i=1(Ai−Aavg)2

其实把这个公式化简一下就知道这个公式的值必定是一个整数,不可能是小数

化简后的公式是(n+m-1)*(A1^2+A2^2+A3^2+……An^2)-(A1+A2+A3+……+An)^2

记Sn=A1+A2+A3+……+An,那么Sn^2=Sn-1^2+2*Sn-1*Ai+Ai*Ai

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define maxn 0x3f3f3f3f
int a[35][35];
int dp[35][35][1000];
int s[35][35],d[35][35];
int main()
{
	int t;
	scanf("%d",&t);
	int cas=1;
	while(t--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				scanf("%d",&a[i][j]);
				s[i][j]=max(s[i-1][j],s[i][j-1])+a[i][j];
				d[i][j]=min(d[i-1][j],d[i][j-1])+a[i][j];
				for(int k=d[i][j];k<=s[i][j];k++)
				{
					dp[i][j][k]=maxn;
				}
			}
		}
		dp[1][1][a[1][1]]=(n+m-1)*a[1][1]*a[1][1]-a[1][1]*a[1][1];
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				for(int k=d[i][j];k<=s[i][j];k++)
				{
					if(dp[i][j][k]==maxn) continue;
					if(i+1<=n) dp[i+1][j][k+a[i+1][j]]=min(dp[i+1][j][k+a[i+1][j]],dp[i][j][k]+(n+m-1)*a[i+1][j]*a[i+1][j]-2*k*a[i+1][j]-a[i+1][j]*a[i+1][j]);
					if(j+1<=m) dp[i][j+1][k+a[i][j+1]]=min(dp[i][j+1][k+a[i][j+1]],dp[i][j][k]+(n+m-1)*a[i][j+1]*a[i][j+1]-2*k*a[i][j+1]-a[i][j+1]*a[i][j+1]);
				}
			}
		}
		int minx=maxn;
		for(int i=d
[m];i<=s
[m];i++)
		{
			minx=min(minx,dp
[m][i]);
		}
		printf("Case #%d: %d\n",cas++,minx);
	}
	return 0;
}


【HDU 5493 Queue】

(N+M−1)∑N+M−1i=1(Ai−Aavg)2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: