2019寒假训练赛⑨解题报告

版权声明:原创文章,欢迎交流。 https://blog.csdn.net/muyu__/article/details/87877000

A - Minimum’s Revenge HDU - 5922

题意:有n个节点,编号为1~n,任意两个点之间的权值为两点编号的最小公倍数,问建最小生成树的最少花费为多少。

题解:最少花费即所有节点都与1号节点连边。

答案为n*(n+1)/2-1

C - Mr. Frog’s Problem HDU - 5924

题意:给出两个数A和B,让你找出C和D满足A/B+B/A<=C/D+D/C,问C、D数对的个数。

题解:满足条件的只有A、B本身。

E - Mr. Frog’s Game HDU - 5926

题意:根据连连看的规则,把两个一样的数字,用三根以下的线连起来(即路线最多变换两次),问能否消除至少一对数字。

题解:

#include<iostream>
#include<cstdio>
using namespace std;
int a[105][105];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int main()
{
    int t;
    scanf("%d",&t);
    for(int k=1;k<=t;k++)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        bool flag=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int z=0;z<4;z++)
                {
                    int mx=i+dx[z],my=j+dy[z];
                    if(mx>=1&&mx<=n&&my>=1&&my<=m)
                    {
                        if(a[mx][my]==a[i][j])
                        {
                            flag=1;
                            break;
                        }
                    }
                }
                if(i==1||i==n)
                {
                    for(int z=1;z<=m;z++)
                    {
                        if(j!=z)
                        {
                            if(a[i][j]==a[i][z])
                            {
                                flag=1;
                                break;
                            }
                        }
                    }
                }
                if(j==1||j==m)
                {
                    for(int z=1;z<=n;z++)
                    {
                        if(i!=z)
                        {
                            if(a[i][j]==a[z][j])
                            {
                                flag=1;
                                break;
                            }
                        }
                    }
                }
            }
        }
        printf("Case #%d: ",k);
        if(flag)
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
}

H - Basic Data Structure HDU - 5929

题意:给你一个栈,支持4种操作。PUSH:将1或0插入队列、POP:将栈顶元素弹出、REVERSE:将栈顶和栈底翻转(把栈倒过来)、QUERY:从栈顶到栈底元素的nand值。(nand:1 nand 1 = 0,1 nand 0 =1, 0 nand 1=1,0 nand 0 =1)。

题解:用双端队列模拟,主要记录离栈顶和栈底 最近和最远的0的位置。

真的难==

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
deque<int>q;
int a[400000+10];
char s[10];
int n;
int main()
{
    int t;
    scanf("%d",&t);
    for(int k=1;k<=t;k++)
    {
        printf("Case #%d:\n",k);
        scanf("%d",&n);
        bool flag=1;
        while(!q.empty())
        {
            q.pop_front();
        }
        int l=n,r=n-1;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            if(s[2]=='S')
            {
                int num;
                cin>>num;
                if(flag)
                {
                    a[++r]=num;
                    if(num==0)
                    q.push_back(r);
                }
                else
                {
                    a[--l]=num;
                    if(num==0)
                    q.push_front(l);
                }
            }
            if(s[2]=='P')
            {
                if(flag)
                {
                    if(a[r]==0) q.pop_back();
                    r--;
                }
                else
                {
                    if(a[l]==0) q.pop_front();
                    l++;
                }
            }
            if(s[2]=='V')
            {
                flag^=1;
            }
            if(s[2]=='E')
            {
                if(q.empty())
                {
                    if(l>r)
                    {
                        printf("Invalid.\n");
                    }
                    else
                    {
                        int sum=r-l+1;
                        if(sum%2==1)
                        {
                            printf("1\n");
                        }
                        else
                        {
                            printf("0\n");
                        }
                    }
                }
                else
                {
                    if(flag)
                    {
                        int sum=q.front()-l;
                        if(sum%2==1)
                        {
                            if(q.front()==r) printf("1\n");
                            else printf("0\n");
                        }
                        else
                        {
                            if(q.front()==r) printf("0\n");
                            else printf("1\n");
                        }
                    }
                    else
                    {
                        int sum=r-q.back();
                        if(sum%2==1)
                        {
                            if(q.back()==l) printf("1\n");
                            else printf("0\n");
                        }
                        else
                        {
                            if(q.back()==l) printf("0\n");
                            else printf("1\n");
                        }
                    }
                }
            }
        }
    }
    return 0;
 }

J - Mission Possible HDU - 5931

题意:有一段长D米的路,走在路上每秒掉A点血,你现在可以花费G1提高1点血上限,花费G2提高1点速度(速度不能超过D),花费G3提高每秒回复能力(先掉血再回复),如果你的血掉到0以下则不能通过,问最少花费多少才能通过这段路。

题解:有两种策略通过这段路。①不回复,只靠血上限硬抗。②先加一下血,再通过回复与掉血持平过去。

我们枚举速度,再比较两种方案的花费,求最小值即可。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    for(int k=1;k<=T;k++)
    {
        long long D,A,G1,G2,G3;
        scanf("%lld%lld%lld%lld%lld",&D,&A,&G1,&G2,&G3);
        long long ans=1e15+7;
        for(int v=1;v<=D;v++)
        {
            long long sum=min((long long)ceil(1.0*D/v*A)*G1,A*G1+A*G3);//向上取整
            ans=min(ans,v*G2+sum);
        }
        printf("Case #%d: %lld\n",k,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/muyu__/article/details/87877000
今日推荐