地址: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,这题想到这里就简单了,不用优化也能过了,呵呵,我就不写代码了