NEFU要崛起——第16场

地址:http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=18757#status

第一题:给你三个点,判断是否是直角三角形,或者把一个顶点移动一单位,使其坐标仍是整数,并且是直角三角形,或者两者都不是,这个只要注意移动后依旧是个三角形就行

代码:

#include<cstdio>
#include<iostream>
using namespace std;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
int x1,x2,x3,y1,y2,y3;
bool IsRight(int a,int b,int c)
{
    if(!(a*b*c))return 0;
    if(a<b)swap(a,b);
    if(a<c)swap(a,c);
    return a==b+c;
}
int sqrdis(int x1,int y1,int x2,int y2)
{
    return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int solve()
{
    if(IsRight(sqrdis(x1,y1,x2,y2),sqrdis(x1,y1,x3,y3),sqrdis(x3,y3,x2,y2)))puts("RIGHT");
    else
    {
        int flag=0;
        for(int i=0;i<4;++i)
        {
            if(IsRight(sqrdis(x1+dx[i],y1+dy[i],x2,y2),sqrdis(x1+dx[i],y1+dy[i],x3,y3),sqrdis(x3,y3,x2,y2)))flag=1;
            if(IsRight(sqrdis(x1,y1,x2+dx[i],y2+dy[i]),sqrdis(x1,y1,x3,y3),sqrdis(x3,y3,x2+dx[i],y2+dy[i])))flag=1;
            if(IsRight(sqrdis(x1,y1,x2,y2),sqrdis(x1,y1,x3+dx[i],y3+dy[i]),sqrdis(x3+dx[i],y3+dy[i],x2,y2)))flag=1;
        }
        if(flag)puts("ALMOST");
        else puts("NEITHER");
    }
}
int main()
{
    while(~scanf("%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3))solve();
    return 0;
}


第二题:模拟一只蚂蚱从左往右跳,问什么时候掉下去,从左往右枚举,每次先跳到平板的最边缘再跳就离开这个平板,然后判断是否能否到达下一个平板就行

代码:

#include<cstdio>
#include<iostream>
using namespace std;
long long i,d,m,l,n,ans;
int main()
{
    while(cin>>n>>d>>m>>l)
    {
        ans=i=0;
        while(++i<=n)
        {
            ans+=(m*(i-1)+l-ans)/d*d;
            if(ans+d<m*i)break;
        }
        ans+=d;
        cout<<ans<<endl;
    }
    return 0;
}


第三题:给你一个数列,问有几种方法能将数列分为两半,使得两半的和相等,这个只要枚举位置,计算和是否相等就行

代码:

#include<cstdio>
#include<iostream>
using namespace std;
const int mm=111111;
int a[mm],sum,n,i,ans;
int main()
{
    while(~scanf("%d",&n))
    {
        sum=ans=a[0]=0;
        for(i=1;i<=n;++i)
            scanf("%d",&a[i]),sum+=a[i];
        for(i=1;i<n;++i)
        {
            a[i]+=a[i-1];
            if(sum-a[i]==a[i])++ans;
        }
        printf("%d\n",ans);
    }
    return 0;
}


第四题:你可以获得一些内存,或者有人会找你买一些内存,但是每次你手上最多有一块内存,问怎样操作是的卖出的钱最多,这题可以转化成区间DP,对于一个获得的内存,向后查找离她最近的买家,如果存在就增加一个i到j的区间,值为卖出该内存的钱,最后求 这些区间不相交的最大值就行,然后需要高精度,注意下2^0次方,没注意看题导致我没过掉这题= =

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
const int mm=5555;
const int mod=100000000;
int a[mm],b[mm],l[mm],r[mm],w[mm],f[mm][999],g[2222][999],tmp[999],s[999];
int i,j,n,m;
char ss[22];
void out(int a[999])
{
    printf("%d",a[a[0]]);
    for(int i=a[0]-1;i>0;--i)printf("%.8d",a[i]);
    puts("");
}
void cpy(int a[999],int b[999])
{
    for(int i=0;i<=b[0];++i)a[i]=b[i];
}
void add(int a[999],int b[999])
{
    int i,k;
    for(i=a[0]+1;i<=b[0];++i)a[i]=0;
    a[0]=max(a[0],b[0]);
    for(i=1,k=0;i<=a[0];++i)
    {
        if(i>b[0])b[i]=0;
        a[i]+=b[i]+k;
        k=a[i]/mod;
        a[i]=a[i]%mod;
    }
    if(k)a[++a[0]]=k;
}
bool cmp(int a[999],int b[999])
{
    if(a[0]<b[0])return 1;
    if(a[0]>b[0])return 0;
    for(int i=a[0];i>0;--i)
    {
        if(a[i]>b[i])return 0;
        if(a[i]<b[i])return 1;
    }
    return 0;
}
int main()
{
    g[0][0]=g[0][1]=1;
    for(i=1;i<=2000;++i)
    {
        cpy(g[i],g[i-1]);
        int k=0;
        for(j=1;j<=g[i][0];++j)
        {
            g[i][j]=g[i][j]*2+k;
            k=g[i][j]/mod;
            g[i][j]%=mod;
        }
        if(k)g[i][++g[i][0]]=k;
    }
    g[2001][0]=1,g[2001][1]=0;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;++i)
            scanf("%s%d",ss,&a[i]),b[i]=(ss[0]=='w');
        m=r[0]=0;
        for(i=1;i<=n;++i)
            if(b[i])
            {
                for(j=i+1;j<=n;++j)
                    if(a[j]==a[i]&&!b[j])
                    {
                        ++m,l[m]=i,r[m]=j,w[m]=a[i];
                        break;
                    }
            }
        l[++m]=1e8,w[m]=w[0]=2001;
        for(i=0;i<=m;++i)f[i][0]=1,f[i][1]=0;
        for(i=1;i<=m;++i)
            for(cpy(s,g[w[i]]),j=0;j<i;++j)
                if(r[j]<l[i])
                {
                    cpy(tmp,f[j]);
                    add(tmp,s);
                    if(cmp(f[i],tmp))cpy(f[i],tmp);
                }
        out(f[m]);
    }
    return 0;
}


第五题:给你一个表格,和一种染色规则,要求最少的修改使得染色满足要求,由于没行只能两种颜色间隔出现,所以只要枚举没行的所有状态,每行的状态只与上行有关,所以可以DP,这题想到这里就简单了,不用优化也能过了,呵呵,我就不写代码了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值