12.9练习

一开始题目都很简单,只要尽可能化简,尤其是数学题(大部分)减少出错的可能性,一遍就可以过了

G题看了没思路,略过,还是要认真思索的,过了5题,剩下的除了没做的,全都有问题,不过还是提交wa了,然后呢看看呗

出错在哪儿了

https://ac.nowcoder.com/acm/contest/289#question

E题分配物资,输出格式有问题,太懒了。

链接:https://ac.nowcoder.com/acm/contest/289/K
来源:牛客网
 

因为现在的新生太强了,都学会了“dp”,所以就有了这样一个“dp”题,双11时Gugugu有(x,x+1,x+2....y-1,y)元的抵用券无数张,但是Gugugu有强迫症所以他希望他使用抵扣券正好能够抵扣k元,这样他就能安心的买下这件商品,但是他却不会计算所以希望你们告诉他能不能一种方法使抵用券正好抵扣k元。

输入描述:

 第一行输入t代表有t组数据,第二行开始每行三个数k,x,y代表需要抵扣k元,x,y代表拥有抵用券的最小面值和最大面值。(1<=t<=200)(1<=k,x,y<109)(x<=y)

输出描述:

输出"Y"代表示能正好抵扣,输出"N"代表不能正好抵扣

示例1

输入

复制

2
7 2 4
6 4 5

输出

复制

Y
N
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll k,x,y;
bool check(ll l,ll r)
{
    for(;l<=r;l++)
    {
        ll left=l*x;
        ll right=l*y;
        if(left<=k&&k<=right)
        return true;
    }
    return false;

}
int main()
{
    int a;
    cin>>a;
    while(a--)
    {

        ll l,r;
        cin>>k>>x>>y;
        l=k/y-1;
        r=k/x+1;

        if(check(l,r))
        cout<<"Y"<<endl;
        else cout<<"N"<<endl;


    }
    return 0;
}

这道题表面上是动态规划,实质上伪装的贪心,切,一开始用了无限背包的模版,因为很典型吗,然后数据过大,怎么也装不下。于是,开始转化。先将k%x,把【x,y】转为[1,x-y]。然后贪心凑出来,最多只能凑k/n次。这个不是我想的,结果以为一定是对的,不能盲从 啊,实际上还是不够优化。应该算出最少配的次数,和最多的次数,遍历,只要算出范围即可(很重要)因为是连续地,本身是有特征的。

我都用面额最小的X来付款,至少需要k/x向上取整,设为Z,用z张钱可以凑出z*x~z*y,只要判断k是否在z*y范围内

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long k,x,y,z;
        scanf("%lld%lld%lld",&k,&x,&y);
        z=k/x;
        if(k<=y*z)
        puts("Y");
        else puts("N");
    }
    return 0;
}

https://ac.nowcoder.com/acm/contest/289/D内心里的一把火,我用的是叉乘,海伦公式不会用,写一下吧

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int x,y;

}a,b,c,d;
double len(node a,node b)
{
    return sqrt(fabs(a.x-b.x)*fabs(a.x-b.x)+fabs(a.y-b.y)*fabs(a.y-b.y));

}
double hailun(node a,node b,node c)
{
    double m,i=len(a,b);
    double j=len(b,c),k=len(a,c);
    m=(i+j+k)/2.0;
    return sqrt(m*fabs(m-i)*fabs(m-j)*fabs(m-k));


}
int main()
{
    while(~scanf("%d%d%d%d%d%d%d%d",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y))
    {
        double q=hailun(a,b,c),w=hailun(a,b,d),e=hailun(a,c,d),r=hailun(c,b,d);
        if(fabs(q-w-e-r)<0.000001)
        {
            puts("YES");
        }
        else puts("NO");

    }

    return 0;


}

https://ac.nowcoder.com/acm/contest/289/J

只要n-(n%10^i+1)即可,保证i-1是9.

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n,d,ans,i;
    while(~scanf("%lld%lld",&n,&d))
    {
        ans=0;
        for(i=10;i<=n;i*=10)
        {
            long long temp=n%i+1;
            if(temp<=d&&temp!=i)
            ans=temp;
            else break;

        }
        printf("%lld",n-ans);
    }

}

题目https://ac.nowcoder.com/acm/contest/289/H

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll aabs(ll a)
{
    if(a<0) return -a;
    else return a;

}
ll maxx(ll a,ll b)
{
    if(a>b) return a;
    else return b;
}
int main()
{
    ll x,y,a;ll d;
    while(~scanf("%lld%lld%lld",&x,&y,&a))
    {x=aabs(x);
    y=aabs(y);
    d=x+y;
    if(d&1) puts("Not the fate");
    else if(maxx(x,y)<a||(max(x,y)-a)%2||x==0&&y==0&&a)
    puts("you are lying");
    else puts("We are together");}
    return 0;
}

走横或纵的最大值,转化为第一象限很容易想到,判断一定是偶数,来是否达到

判断是否说谎,从最短路与所给的比较,还有相减是否为奇数或者偶数,最大的坑(就是这个我完全没想到)小学妹位置(0,0)的时候002,004 说谎,只有000对的。读题要注意细节,我本来以为一遍我只要用到所有条件,如果还wa的话,一定是我做不出来,现在想来,根本无法判断是否全用到了啊,不可以仅靠感觉。

题目https://ac.nowcoder.com/acm/contest/289/I

字符串重新排序后能否组成K个相同的字符串

#include<bits/stdc++.h>
using namespace std;
char s[1050];
char str[1050];
#define ll long long
int vis[77];
int main()
{
    int  k;
    while(~scanf("%d",&k))
    {
        scanf("%s",&s);
        memset(vis,0,sizeof((vis)));
        int l=strlen(s);
        if(l%k!=0)
        {
            puts("-1");
            continue;
        }
        for(int i=0;i<l;i++)
        {
            vis[s[i]-'a']++;
        }
        bool f=false;
        int tt=0;
        for(int i=0;i<26;i++)
        {
            if(vis[i]>0)
            {if(vis[i]%k!=0)
            {
                f=true;
            }
            for(int j=1;j<=vis[i]/k;j++)
            {
                str[tt++]='a'+i;
            }
            }
        }
        str[tt]='\0';
        if(f)
        puts("-1");
        else
        {
            for(int i=1;i<=k;i++)
            {
                printf("%s",str);
            }
            //fflush(stdin);
        }
    }
}

至于这道为什么错,估计是写的复杂了,细节问题吧,做了一个小时题目,心情有点烦躁了。

题目:https://ac.nowcoder.com/acm/contest/289/G

消掉小球吧

#include<stdio.h>
#include<string.h>
char c[100005],w[5],q;
bool judge(char c[],char w)
{
    int r=strlen(c)-1;
    int l=0,num;
    while(l<r)
    {
        if(c[l]!=c[r])
        {
            return 0;
        }
        num=0;
        q=c[r];
        while(c[l]==q)
        {
            num++;
            l++;
        }
        while(c[r]==q&&r>=l)
        {
            num++;
            r--;
        }

        if(num<3&&(num!=2||l!=r+1))
        {
            return 0;
        }
    }
        if(q==w) return 1;
        return 0;


}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s %s",w,c);
        if(judge(c,w[0]))
        {
            puts("yes");
        }
        else puts("no");
    }
    return 0;
}

注意去重,两种情况不满足,逆向思维。模拟,说明我脑抽了,这种题目还是做得出来的。结果我这是什么状况,想了一秒,感觉很麻烦就撤了?看来下次要要求自己全做出来了。否则不想做是个麻烦事。注意格式,一次没过的话,就两次,尽量还是一次吧。还是要化到最简。别被题目误导了。

猜你喜欢

转载自blog.csdn.net/qq_42865713/article/details/84932148
今日推荐