2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest(补题中)

加粗:赛时AC 

普通:赛后AC

A. Xu Xiake in Henan Province

水题,有几个零就输出对应的语句。

B. Ultraman vs. Aodzilla and Bodzilla

有人打的时候非要雪花勇闯天涯去做没人出的题,我不说是谁.jpg

模拟+贪心,这题的细节非常多而且繁杂。

首先我们必须明确,结束战斗的回合数是一定的,也就是把hpa+hpb刚好砍完的那一刻,既然回合一定,那么就一定要先解决掉一个怪兽使得收到的伤害最少。

那么我们会发现,先把A杀掉或者先把B杀掉的回合数也是一定的,但是如果把刀集中在一起,由于伤害是递增的,就会造成伤害溢出的情况。所以用可能会将前面溢出的一些伤害打在另一只怪兽身上。

最难的部分体现在要按照字典序输出,我们分类讨论:

一.如果先杀A的伤害更低,我们记录一个杀A溢出伤害x和一个最终溢出伤害y,那么:

1.假如y为正数,就说明目前B还没有死亡,此时x的绝对值一定大于y的绝对值,就需要在前面把A刀转为B刀,基于字典序最小的规定,一定是把刚好等于溢出伤害的地方转为B刀。

2.假如y为负数,就不需要更改。

二、如果先杀B的伤害更低,我们记录一个杀B溢出伤害x和一个最终溢出伤害y,那么:

无论y是否为负数,此时x的绝对值一定大于y的绝对值,就需要在前面把B刀转为A刀,基于字典序最小的规定,注意,由于 ‘A’<‘B’ ,所以应该是从第1个到刚好伤害到达小于等于x的绝对值的时候全部转为A刀,但是,这个转换有一个很特殊的情况:

如果y是正数的话,那么B刀转为A刀的时候一定要保证y<=伤害<=x,才能够保证击杀掉A也杀掉B(y是负数的话转A刀就不用考虑必须杀死A,因为A已经死了)。此时,假如我们从小到大一个个从1开始转A刀的话,就有可能在最后一刀的时候刚好伤害>x,而少了这一刀的话就伤害<y,此时我们要退一步,然后去后面把差的伤害那一道转为A。

三、如果两种击杀方式相等,此时我们并不能够保证那种情况的字典序最小,最好的办法就是两种都做一遍然后选择答案更合适的输出

#include<iostream> 
#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
#include<algorithm>
#include<queue>
#define N 1000010
#define ll long long
using namespace std;
ll a[N],T;
ll hpa,hpb,atka,atkb;
char ch[N],ch2[N];
//快读 
inline void read(ll &p)
{
    p=0;
    ll f=1;char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') p=p*10+(ch-'0'),ch=getchar();
    p*=f;
}


int main()
{
    read(T);
    for(int i=1;i<=N-10;i++) a[i]=a[i-1]+i;
    while(T--)
    {
        read(hpa);read(hpb);
        read(atka);read(atkb);
        
        
        ll shaab=lower_bound(a+1,a+1+N,hpa+hpb)-a;
        ll shaa=lower_bound(a+1,a+1+N,hpa)-a;
        ll shab=lower_bound(a+1,a+1+N,hpb)-a;
        ll shanga=0,shangb=0;
        ll limhpa=hpa,limhpb=hpb,limhpb2=limhpb,limhpa2=hpa;
        int i;
        
        for(i=1;i<=shaa;i++) shanga+=(atka+atkb),limhpa2-=i;
        for(i=shaa+1;i<=shaab;i++) shanga+=atkb,limhpb-=i;
        
        
        
        for(i=1;i<=shab;i++) shangb+=(atka+atkb),limhpb2-=i;
        for(i=shab+1;i<=shaab;i++) shangb+=atka,limhpa-=i;
        
        
            for(i=1;i<=shaa;i++) ch[i]='A';
            for(i=shaa+1;i<=shaab;i++) ch[i]='B';
            //伤害区间(limhpb-abs(limhpa1)) 
            if(limhpb>0) ch[abs(limhpa2)]='B';
            for(i=1;i<=shab;i++) ch2[i]='B';
            for(i=shab+1;i<=shaab;i++) ch2[i]='A';
            ll limms=0;
                for(i=1;i<=shab;i++)
                {
                    if(limms>=limhpa) break;
                    limms+=i;
                    ch2[i]='A';
                }
                if(limms>abs(limhpb2))
                {
                    ch2[i-1]='B';
                    ch2[i-2]='B';
                    i--;
                    limms-=i;
                    i--;
                    limms-=i;
                    for(i;i<=shab;i++)
                    {
                        if(limms+i>limhpa) break;
                    }
                    ch2[i-1]='A';
                }
                else
                {
                    for(i;i<=shab;i++)
                    {
                        if(limms>abs(limhpb2)) break;
                        ch2[i]='A';
                        limms+=i;
                    }
                    ch2[i-1]='B';
                }
        if(shanga<shangb) 
        {
            printf("%lld ",shanga);
            for(int i=1;i<=shaab;i++) printf("%c",ch[i]);
        }
        else if(shanga>shangb)
        {
            printf("%lld ",shangb);
            for(int i=1;i<=shaab;i++) printf("%c",ch2[i]);
        }
        else
        {
            printf("%lld ",shanga);
            bool f=1;
            for(int i=1;i<=shaab;i++)
            {
                if(ch[i]<ch2[i]) {f=0;break;}
                else if(ch[i]>ch2[i]){f=1;break;}
            }
            if(f) for(int i=1;i<=shaab;i++) printf("%c",ch2[i]);
            else for(int i=1;i<=shaab;i++) printf("%c",ch[i]);
        }
        printf("\n");
    }
    return 0;
}

/*
1
5 5 1 1

5
5 15 5 25
5 15 25 5
251765086 586338075 348202 6436188
23 76 3 33

*/
View Code

D. Keiichi Tsuchiya the Drift King

数学题,杰哥做的,我看不懂,弃疗.jpg

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <functional>

#include <cmath>

using namespace std;
typedef long long ll;
#define finc(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define fdec(i,a,b) for(int i=(int)(b);i-->(int)(a);)
#define reset(a,...) a=decltype(a)(__VA_ARGS__)
#define endl '\n'
#define endb ' '
#define read(a,str) scanf("%"#str,&a)
#define print(a,str) printf("%"#str,a)

const double pi = acos(-1);

double dis(double a, double b)
{
    return sqrt(a * a + b * b);
}

void ac()
{
    double a, b, r, d;
    cin >> a >> b >> r >> d;
    double delta = pi * d / 180, now = atan(b / (a + r));
    if (delta >= now)
    {
        printf("%.9lf\n", dis(a + r, b) - r);
        return;
    }
    double ans = dis(a + r, b);
    ans *= cos(now - delta);
    printf("%.9lf\n", ans - r);
}

int main()
{
    //ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int test = 1; cin >> test;
    while (test--)
        ac();

    return 0;
}
View Code

E. Resistors in Parallel

这题有点让人无语,我是打了个表发现规律的,至于为什么我不是很清楚,后续会补上的。

总的来说就是以质数的积为界限,以质数+1的积为答案,但是由于数字有点大,所以需要高精度,或者用别的语言,我是用py写得。

学习一门外语真是非常重要啊.jpg

F. Honeycomb

模拟题,是壕哥写得,写得时候注意字符该怎么处理,注意cin和getline的速度很慢,所以T了很多发,gets的速度会快很多。

#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <string>
using namespace std;
int mo[6][2]= {{-1,-3},{-1,3},{1,-3},{1,3},{-2,0},{2,0}};
char mp[4000+10][6000+10];
struct node
{
    int x,y,num;
};
queue<node> q;
int v[4000+10][6000+10];
node a,b;
int r,c;
void read()
{
    int i,j;
    for (i=0; i<4*r+3; i++)
    {
        gets(mp[i]);
        for (j=0; mp[i][j]; j++)
        {
            v[i][j]=0;
            if (mp[i][j]=='S')
            {
                a.x=i;
                a.y=j;
            }
            else if (mp[i][j]=='T')
            {
                b.x=i;
                b.y=j;
            }
        }
    }
    a.num=1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        int i,j;
        scanf("%d%d",&r,&c);
        getchar();
        read();
        q.push(a);
        v[a.x][a.y]=1;
        int ans=-1;
        while (!q.empty())
        {
            node now=q.front();
            q.pop();
            for (i=0; i<6; i++)
            {
                int x=now.x+mo[i][0],y=now.y+mo[i][1];
                if (x<0||y<0||x>=4*r+3||y>=6*c+3||mp[x][y]!=' ')
                    continue;
                node neww;
                neww.x=x+mo[i][0],neww.y=y+mo[i][1];
                if (neww.x<0||neww.y<0||neww.x>=4*r+3||neww.y>=6*c+3)
                    continue;
                if (neww.x==b.x&&neww.y==b.y)
                {
                    ans=now.num+1;
                    v[neww.x][neww.y]=1;
                    break;
                }
                if (v[neww.x][neww.y]) continue;
                v[neww.x][neww.y]=1;
                neww.num=now.num+1;
                q.push(neww);
            }
            if (ans!=-1)
                break;
        }
        while (!q.empty())
            q.pop();
        printf("%d\n",ans);
    }
    return 0;
}
/*
  +---+       +---+
 /     \     /     \
+       +---+       +---+
 \           \     /     \
  +   +   S   +---+   T   +
 /     \     /           /
+       +---+       +   +
 \           \     /     \
  +---+       +---+       +
 /                       /
+       +---+       +   +
 \                 /     \
  +---+       +---+       +
       \     /     \     /
        +---+       +---+
*/
View Code

I. Distance

思维题,首先确定策略,策略是每两次都加入最外围没有加入答案的两棵树木,在这两次之间的答案增量是一样的,而在第二次时会改变增量。

 

posted @ 2022-04-30 19:59  ztlsw  阅读(42)  评论(0编辑  收藏  举报