M-SOLUTIONS Programming Contest 2020

目录

        • A Kyu in AtCoder
        • B Magic 2
        • C Marks
        • D Road to Millionaire
        • E M's Solution
        • F Air Safety



题目地址:https://atcoder.jp/contests/m-solutions2020



A Kyu in AtCoder

题意:水题

思路

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

int main()
{
    int x=read();
    if(x<600) putchar('8');
    else if(x<800) putchar('7');
    else if(x<1000) putchar('6');
    else if(x<1200) putchar('5');
    else if(x<1400) putchar('4');
    else if(x<1600) putchar('3');
    else if(x<1800) putchar('2');
    else if(x<2000) putchar('1');

    return 0;
}



B Magic 2

题意:水题

思路

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

int main()
{
    int a=read(),b=read(),c=read(),k=read();
    int tot=0;
    while(b<=a) b<<=1,tot++;
    while(c<=b) c<<=1,tot++;
    puts(tot<=k?"Yes":"No");

    return 0;
}



C Marks

题意:水题

思路

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

const int maxn=2e5+5;
int n,k,a[maxn];

int main()
{
    n=read(),k=read();
    REP(i,1,n) a[i]=read();
    REP(i,k+1,n) puts(a[i]>a[i-k]?"Yes":"No");

    return 0;
}



D Road to Millionaire

题意:炒股问题。

思路:只需要遍历一次每天的价格,如果比前一天高,那么就在前一天尽可能多买股票,然后今天全部卖掉。这样是最优的。

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

LL n,a[100];

int main()
{
    n=read();
    REP(i,1,n) a[i]=read();
    LL m=1000;
    REP(i,2,n) if(a[i]>a[i-1]) m+=m/a[i-1]*(a[i]-a[i-1]);
    cout<<m;

    return 0;
}



E M’s Solution

题意:在直角坐标系中,每一条与 x 轴或者 y 轴平行的整直线(也就是与 x 轴或者 y 轴距离为整数)都是公路,一开始只有 x 轴和 y 轴是修建好的公路,其它的位置都没有修。现在有 n( 1 ≤ n ≤ 15 1\le n\le 15 1n15) 个城市,分别坐落于不同的整数坐标处,每个城市有一个人口数 p,你最多可以修建 K 条公路,然后定义 walking distance 为城市中的人走到最近的公路的距离,你的任务是使得所有人的 walking distance 之和最小,并且输出对于每个 K( 0 ≤ K ≤ n 0\le K \le n 0Kn),这个最小值是多少。

思路:首先我们可以知道,最优方案中公路一定至少经过一个城市,因为如果不经过城市,也可以平移到最近的城市,距离不会变长。再者一个城市最多只经过一条公路,因为如果经过了两条,那么第二条对于这个城市来说就是一种冗余,不如让这条公路经过其它城市。所以很容易想到每个城市可能有三个状态:没公路、有一条横着的公路、有一条竖着的公路。总共的状态数为 3 n 3^n 3n 大概是 1 e 7 1e7 1e7 的规模。然后对于每种状态,把有公路的拎出来,然后对于每个城市去计算最近距离统计答案,然后更新答案,复杂度大概是 O ( 3 n n 2 ) O(3^nn^2) O(3nn2),计算的时候加上一些剪枝,而且本来很多状态也不用 n 2 n^2 n2 的复杂度去计算,最后勉强过了。

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<LL,LL> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

const int maxn=16;
LL n,x[maxn],y[maxn],p[maxn],ans[maxn],m[maxn];
LL xx[maxn],yy[maxn];
int a[maxn],nx,ny;

void solve(int q)
{
    int tot=0;
    REP(i,1,n)
    {
        a[i]=q%3; q/=3;
        if(a[i]>0) tot++;
    }

    nx=ny=0;
    REP(i,1,n)
        if(a[i]==1) xx[++nx]=x[i];
        else if(a[i]==2) yy[++ny]=y[i];
    REP(i,1,n) m[i]=3e18;
    LL t=0;
    REP(i,1,n)
    {
        REP(j,1,nx) m[i]=min(m[i],abs(xx[j]-x[i]));
        REP(j,1,ny) m[i]=min(m[i],abs(yy[j]-y[i]));
        m[i]=min(m[i],abs(x[i]));
        m[i]=min(m[i],abs(y[i]));
        t+=m[i]*p[i];
        if(t>=ans[tot]) return;
    }
    ans[tot]=min(ans[tot],t);

}

int main()
{
    n=read();
    REP(i,1,n) x[i]=read(),y[i]=read(),p[i]=read();
    REP(i,0,n) ans[i]=3e18;
    int q=1;
    REP(i,1,n) q*=3;
    REP(i,0,q-1) solve(i);
    REP(i,0,n) printf("%lld\n",ans[i]);

    return 0;
}



F Air Safety

题意:无限大的平面中,有 n( 1 ≤ n ≤ 2 e 5 1\le n\le 2e5 1n2e5) 个飞机在飞行,每个飞机只可能有四个方向:上下左右,并且飞行方向不会变,并且每架飞机的飞行速度都相等为 0.1单位/秒。给定每架飞机的位置( 0 ≤ X i , Y i ≤ 2 e 5 0\le X_i,Y_i\le2e5 0Xi,Yi2e5)和方向,问是否会发生相撞,如果发生输出距离相撞的时间,如果不会输出“SAFE”。

思路:发生相撞只可能有以下几种情况:(1)平行于 x 轴飞行,左边的往右飞,右边的往左飞;(2)平行于 y 轴飞行,上面的往下飞,下面的往上飞;(3)平行于 y=x 这条直线,左下的往上飞、右上的往左飞,或者左下的往右飞、右上的往下飞;(4)平行于 y=-x 这条直线,…… 。只有这四种情况。所以读入每架飞机的位置之后,按照这四个轴分别存储,然后先预处理飞机一开始重叠的情况,然后按照 x 第一关键字,y 第二关键字排个序,然后每条轴上分别处理即可。

因为已经排好了序,而且相撞的情况可以枚举,所以没什么难度。

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<LL,LL> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

const int maxn=1e6+5,v=5e5,N=1e6;
struct node {int x,y,dir;} a[maxn];
VI x[maxn],y[maxn],p[maxn],q[maxn];
int n,ans=1e9;
char s[10];
bool cmp1(int i,int j) {return a[i].x==a[j].x?a[i].y<a[j].y:a[i].x<a[j].x;}
bool cmp2(int i,int j) {return a[i].y==a[j].y?a[i].x<a[j].x:a[i].y<a[j].y;}

int main()
{
    n=read();
    REP(i,1,n)
    {
        a[i].x=read();
        a[i].y=read();
        scanf("%s",s);
        a[i].dir=s[0];
    }
    sort(a+1,a+n+1,[&](node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;});
    REP(i,2,n) if(a[i].x==a[i-1].x && a[i].y==a[i-1].y) return puts("0"),0;
    REP(i,1,n)
    {
        x[a[i].x+v].pb(i);
        y[a[i].y+v].pb(i);
        p[a[i].y-a[i].x+v].pb(i);
        q[a[i].y+a[i].x+v].pb(i);
    }

    REP(i,1,N)
    {
        sort(x[i].begin(),x[i].end(),cmp1);
        sort(y[i].begin(),y[i].end(),cmp2);
        sort(p[i].begin(),p[i].end(),cmp1);
        sort(q[i].begin(),q[i].end(),cmp1);
    }

    REP(i,1,N) if(x[i].size()>1)
    {
        int yy=-1;
        REP(j,0,x[i].size()-1)
        {
            int id=x[i][j];
            if(yy>=0 && a[id].dir=='D') ans=min(ans,abs(a[id].y-yy)*5);
            if(a[id].dir=='U') yy=a[id].y;
        }
    }
    REP(i,1,N) if(y[i].size()>1)
    {
        int xx=-1;
        REP(j,0,y[i].size()-1)
        {
            int id=y[i][j];
            if(xx>=0 && a[id].dir=='L') ans=min(ans,abs(a[id].x-xx)*5);
            if(a[id].dir=='R') xx=a[id].x;
        }
    }
    REP(i,1,N) if(p[i].size()>1)
    {
        int xx1=-1,xx2=-1;
        REP(j,0,p[i].size()-1)
        {
            int id=p[i][j];
            if(xx1>=0 && a[id].dir=='L') ans=min(ans,abs(a[id].x-xx1)*10);
            if(xx2>=0 && a[id].dir=='D') ans=min(ans,abs(a[id].x-xx2)*10);
            if(a[id].dir=='U') xx1=a[id].x;
            if(a[id].dir=='R') xx2=a[id].x;
        }
    }
    REP(i,1,N) if(q[i].size()>1)
    {
        int xx1=-1,xx2=-1;
        REP(j,0,q[i].size()-1)
        {
            int id=q[i][j];
            if(xx1>=0 && a[id].dir=='U') ans=min(ans,abs(a[id].x-xx1)*10);
            if(xx2>=0 && a[id].dir=='L') ans=min(ans,abs(a[id].x-xx2)*10);
            if(a[id].dir=='R') xx1=a[id].x;
            if(a[id].dir=='D') xx2=a[id].x;
        }
    }
    if(ans>=(1e9)-1) puts("SAFE");
    else printf("%d\n",ans);

    return 0;
}

你可能感兴趣的:(atcoder)