题意:给出3个点,其坐标都是整数,如果这三个点能组成直角三角形输出"RIGHT",如果不是直角三角形,但是将某个点的坐标移动一个整数的位置(上下左右),移动后三个点组成直角三角形则输出"ALMOST",都不是则输出"NEITHER"
由于数据较小,枚举即可,但是要注意在移动点时,不要与其他点重合
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define M 4
double x[M],y[M],line[M];//line是三角形的边
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
double dis(int a,int b)//求两点间的距离
{
return (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]);
}
int main()
{
scanf("%lf%lf%lf%lf%lf%lf",&x[1],&y[1],&x[2],&y[2],&x[3],&y[3]);
line[1]=dis(1,2);
line[2]=dis(1,3);
line[3]=dis(2,3);
sort(line+1,line+4);
if(line[1]+line[2]==line[3]) //a^2+b^2=c^2
{
printf("RIGHT\n");
return 0;
}
for(int i=1;i<=3;i++) //枚举每个点
{
for(int k=0;k<4;k++)//四个方向
{
x[i]+=dx[k]; y[i]+=dy[k];
bool f=true;
for(int j=1;j<=3;j++)//防止与其他点重合
{
if(j==i) continue;
if(x[i]==x[j]&&y[i]==y[j]) {f=false;break;}
}
if(f)
{
line[1]=dis(1,2);
line[2]=dis(1,3);
line[3]=dis(2,3);
sort(line+1,line+4);
if(line[1]+line[2]==line[3])
{
printf("ALMOST\n");
return 0;
}
}
x[i]-=dx[k]; y[i]-=dy[k];
}
}
printf("NEITHER\n");
return 0;
}
题意:现有屏幕长和宽分别为X,Y,问能否将其切割为长宽比例为a:b的一块屏幕,要使切出来的屏幕面积尽量大
解析:注意长宽是不能互换的,此题最坑之处在于若a和b有最大公约数要将a和b都除以最大公约数,
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define M 100005
ll a,b,x,y;
ll gcd(ll a,ll b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
cin>>a>>b>>x>>y;
ll g=gcd(x,y);
x=x/g;y=y/g;
if(x>a||y>b)//如果x>a||y>b是切不出来的,因为此时屏幕面积最小a*b,其余情况至少能切为a*b
{
cout<<0<<" "<<0<<endl;
return 0;
}
ll ansa=0,ansb=0;
if(x>=y)
{
//if(a<b) swap(a,b);
ll tmp=a/x;
a=tmp*x; //确定能到达的宽的最大值,用它去试长度
while(b<tmp*y)//满足宽为a的长tmp*y大于b,此时通过缩小宽度a来缩小所需的长度继续试
{
a-=x;
tmp--;
}
ansa=a;
ansb=tmp*y;
}else{
//if(a>b) swap(a,b);
ll tmp=b/y;
b=tmp*y;
while(a<tmp*x)
{
b-=y;
tmp--;
}
ansa=tmp*x;
ansb=b;
}
if(ansa<0||ansb<0)
cout<<0<<" "<<0<<endl;
else
cout<<ansa<<" "<<ansb<<endl;
return 0;
}
CodeForces - 22B - Bargaining Table
题意:有n*m房间,用01矩阵表示,0表示空闲,1表示有东西在此位置,问此房间里最大能放一个边长多大的矩形桌子
解析:枚举桌子大小即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define M 35
int n,m;
char str[M][M];
bool solve(int x,int y)//x,y为桌子的长和宽
{
for(int i=0;i+x-1<n;i++)
{
for(int j=0;j+y-1<m;j++) //(i,j)为桌子左上角
{
bool f=true;
for(int w=0;w<x;w++)
{
for(int h=0;h<y;h++)//去检查桌子所在位置的每个点
{
int xx=i+w;
int yy=j+h;
if(str[xx][yy]=='1') f=false;
}
}
if(f==true) return true;
}
}
return false;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
scanf("%s",str[i]);
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(solve(i,j))
{
ans=max(ans,2*i+2*j);
}
}
}
cout<<ans<<endl;
return 0;
}
题意:在一个直线上有n个平台。 第k个平台(平台从1开始编号)是坐标为[(k-1)*m,(k-1)*m+L]且(l <m)的一段。 Bob 从坐标为0点开始沿着直线跳跃,每次跳跃移动d个单位, 找出鲍勃将落下的点的坐, 如果Bob不在平台上,Bob就会掉下来,在平台的边缘,不算掉下。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define M 1005
ll n,d,m,l;
int main()
{
cin>>n>>d>>m>>l;
ll low=0,hig=l;
ll pos=0,k=1;
while(1) //当前循环中Bob位于pos,
{
if(k>n) break;//k是当前到了哪块平台
low=(k-1)*m; //low,hig平台两端
hig=(k-1)*m+l;
if(pos<=hig) pos=pos+((hig-pos)/d+1)*(d);//如果Bob在平台上,那么让Bob走(hig-pos)/d+1步使得Bob离开当前k平台
if(k<n&&pos<k*m)//平台走完,或到达不了下一个平台就退出
{
break;
}
k++;
}
cout<<pos<<endl;
return 0;
}
CodeForces - 4B - Before an Exam
题意:总共有时间sum,有d天,每天学习时间不能少于L[i],每天学习时间不能超过R[i],问能否成功的将sum分到d天,能的话要输出每天的学习时间
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define M 35
int n,sum,l[M],r[M],ans[M],totl[M],totr[M];//totl[i],totr[i]分别是到第i天的最少、最多学习时间和
int main()
{
scanf("%d%d",&n,&sum);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&l[i],&r[i]);
totl[i]=totl[i-1]+l[i];
totr[i]=totr[i-1]+r[i];
}
if(sum<totl[n]||sum>totr[n])
{
cout<<"NO"<<endl;
}else{
int tot=0;
for(int i=n;i>=1;i--) //从后往前,确定每天时间
{
for(int k=l[i];k<=r[i];k++)//枚举当前天用时间k是否可以
{
if((sum-(tot+k))>=totl[i-1]&&(sum-(tot+k))<=totr[i-1])//sum-(tot+k)是给前面i-1天的总时间
{
tot+=k;
ans[i]=k;
break;
}
}
}
cout<<"YES"<<endl;
for(int i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}
CodeForces - 6C - Alice, Bob and Chocolate
题意:有n个巧克力,从左到右摆开,每块需要a[i]个单位时间能吃完,Alice从左边开始吃,Bob从右边开始吃,若两个人同时遇到同一块巧克力让Alice吃,问每个人分别吃了几个
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define M 100005
int n,t[M];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&t[i]);
if(n==1)//只有一个A吃
{
cout<<1<<" "<<0<<endl;
return 0;
}
int a=1,b=n;
ll tima=t[1];//tima为A吃到第a块花的时间
ll timb=t[n];//timb为B吃到第B块花的时间
while(a+1<b)//Alice在吃序号为a的,Bob在吃序号为b的
{
if(tima>timb)//Alice吃完第a块要到tima,而Bob到timb就吃完第b块了,所以Bob再吃一块
{
b--;
timb+=t[b];
}else{
a++;
tima+=t[a];
}
}
cout<<a<<" "<<n-a<<endl;
return 0;
}