java div2_CF183 div2 解题报告

A. Pythagorean Theorem II

题目链接:

题目意思:

求出满足1<=a<=b<=c<=n,且a^2+b^2=c^2,的a,b,c的个数,其中n<=10^4.

解题思路:

如果用0(n^3)的话肯定超时(我就是轻估了题目,然后被hack掉了。。。),枚举a,b,然后求出c,是否在1-n的范围内。

代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define eps 1e-10

#define INF (1<<30)

#define PI acos(-1.0)

using namespace std;

int main()

{

int a,b,c,n;

__int64 num;

while(scanf("%d",&n)!=EOF)

{

num=0;

for(a=1;a<=n;a++)

for(b=a;b<=n;b++)

{

double c=a*a+b*b;

if(c>n*n)

continue;

c=fabs(sqrt(c*1.0)-(int)(sqrt(c*1.0)+.5)); //注意四舍五入的处理

if(c<=eps)

num++;

}

printf("%I64d\n",num);

}

return 0;

}

B. Calendar

题目链接:

题目意思:

给出两个日期,求出两个日期之间的天数,天数包括第一个日期,不包括最后一个日期。

解题思路:

模拟题,就分段处理,注意当前一个日期比后一个日期大的话,要交换下。

代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define eps 1e-6

#define INF (1<<30)

#define PI acos(-1.0)

using namespace std;

int days[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,

0,31,29,31,30,31,30,31,31,30,31,30,31};

//days[0][i],表示平年的第i月的天数,days[1][i]表示闰年的第i月天数

int num[2]={365,366}; //num[0]表示平年的天数,num[1]表示闰年的天数

int isleap(int year) //判断是否是闰年

{

if((year%4==0&&year%100)||year%400==0)

return 1;

return 0;

}

int y11,m1,d1,y2,m2,d2;

bool Change() //是否要交换

{

if(y11

return true;

else if(y11>y2)

return false;

if(m1

return true;

else if(m1>m2)

return false;

if(d1

return true;

else if(d1>d2)

return false;

}

int main()

{

while(scanf("%4d:%2d:%2d",&y11,&m1,&d1)!=EOF)

{

scanf("%4d:%2d:%2d",&y2,&m2,&d2);

if(Change()==false) //前一个日期在后一个日期的后面,交换

{

swap(y11,y2);

swap(m1,m2);

swap(d1,d2);

}

//printf("%d %d %d\n%d %d %d\n",y11,m1,d1,y2,m2,d2);

int ans=0;

if(y11==y2) //在同一年

{

int leap=isleap(y11);

if(m1==m2)

ans=d2-d1+1;

else

{

ans+=days[leap][m1]-d1+1;

for(int i=m1+1;i

ans+=days[leap][i];

ans+=d2;

}

}

else

{

int leap1=isleap(y11);

ans+=days[leap1][m1]-d1+1;

for(int i=m1+1;i<=12;i++) //这一年中间的几个月

ans+=days[leap1][i];

for(int i=y11+1;i

ans+=num[isleap(i)];

int leap2=isleap(y2); //后一日期的该年的天数

for(int i=1;i

ans+=days[leap2][i];

ans+=d2;

}

printf("%d\n",ans-1);

}

return 0;

}

C. Lucky Permutation Triple

题目链接:

题目意思:

求三个大小为n的数组,他们的元素为0——n-1,同一数组中各元素都不相同,如果能够找到(a[i]+b[i]=c[i]%n,则输出其中的任意一个,否则输出-1.

解题思路:

当n为偶数的时候,不能凑出。

当n为奇数的时候,可以通过移一位凑出。

代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define eps 1e-6

#define INF (1<<30)

#define PI acos(-1.0)

using namespace std;

int a[120000],b[120000],c[120000];

int main()

{

int n;

while(scanf("%d",&n)!=EOF)

{

if(n&1)

{

for(int i=0;i

{

a[i]=i;

b[i]=(i+1)%n;

c[i]=(a[i]+b[i])%n;

}

printf("%d",a[0]);

for(int i=1;i

printf(" %d",a[i]);

putchar('\n');

printf("%d",b[0]);

for(int i=1;i

printf(" %d",b[i]);

putchar('\n');

printf("%d",c[0]);

for(int i=1;i

printf(" %d",c[i]);

putchar('\n');

}

else

printf("-1\n");

}

return 0;

}

D. Rectangle Puzzle II

题目链接:

解题思路:

就是先求(a,b)的最大公约数,然后分别除掉,求出在(n,m)范围的最大的长度和宽度,容易证明,对任意的(x,y),一定可以包含,所以以(x,y)为中心,以长度和宽度的一半为距离(当为奇数的时候,向左和下倾斜),做矩形,然后分别判断,上下左右,在不在(n,m)内,如果下不在,则往上移,一直到下为0,依次搞定其他个方向。

代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define eps 1e-6

#define INF (1<<30)

#define PI acos(-1.0)

using namespace std;

int n,m,x,y,a,b;

int gcd(int aa,int bb)

{

if(aa%bb==0)

return bb;

return gcd(bb,aa%bb);

}

int main()

{

int anle,anri,anup,ando;

while(scanf("%d%d%d%d%d%d",&n,&m,&x,&y,&a,&b)!=EOF)

{

int temp=gcd(a,b);

a=a/temp,b=b/temp;

int len,wid;

if(n/a>m/b) //求出最大的长和宽

{

len=m/b*a;

wid=m/b*b;

}

else

{

len=n/a*a;

wid=n/a*b;

}

//以(x,y)为中心,最大长度和宽度建立矩形,奇数的话向下和向左倾斜

anle=x-(len-len/2),anri=x+len/2;

anup=y+wid/2,ando=y-(wid-wid/2);

//一次判定各个方向是否超出了界限,超了话,朝相反的方向移动

if(anri>n)

{

anle-=anri-n;

anri-=anri-n;

}

if(anle<0)

{

anri+=-anle;

anle=0;

}

if(anup>m)

{

ando-=anup-m;

anup-=anup-m;

}

if(ando<0)

{

anup+=-ando;

ando=0;

}

printf("%d %d %d %d\n",anle,ando,anri,anup);

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值