A. Pythagorean Theorem II
题目链接:
http://codeforces.com/contest/304/problem/A
题目意思:
求出满足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<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<queue>
#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
题目链接:
http://codeforces.com/contest/304/problem/B
题目意思:
给出两个日期,求出两个日期之间的天数,天数包括第一个日期,不包括最后一个日期。
解题思路:
模拟题,就分段处理,注意当前一个日期比后一个日期大的话,要交换下。
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<stack> #include<list> #include<queue> #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<y2) return true; else if(y11>y2) return false; if(m1<m2) return true; else if(m1>m2) return false; if(d1<d2) 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<m2;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<y2;i++) //中间的几年 ans+=num[isleap(i)]; int leap2=isleap(y2); //后一日期的该年的天数 for(int i=1;i<m2;i++) ans+=days[leap2][i]; ans+=d2; } printf("%d\n",ans-1); } return 0; }
C. Lucky Permutation Triple
题目链接:
http://codeforces.com/contest/304/problem/C
题目意思:
求三个大小为n的数组,他们的元素为0——n-1,同一数组中各元素都不相同,如果能够找到(a[i]+b[i]=c[i]%n,则输出其中的任意一个,否则输出-1.
解题思路:
当n为偶数的时候,不能凑出。
当n为奇数的时候,可以通过移一位凑出。
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<stack> #include<list> #include<queue> #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<n;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<n;i++) printf(" %d",a[i]); putchar('\n'); printf("%d",b[0]); for(int i=1;i<n;i++) printf(" %d",b[i]); putchar('\n'); printf("%d",c[0]); for(int i=1;i<n;i++) printf(" %d",c[i]); putchar('\n'); } else printf("-1\n"); } return 0; }
D. Rectangle Puzzle II
题目链接:
http://codeforces.com/contest/304/problem/D
解题思路:
就是先求(a,b)的最大公约数,然后分别除掉,求出在(n,m)范围的最大的长度和宽度,容易证明,对任意的(x,y),一定可以包含,所以以(x,y)为中心,以长度和宽度的一半为距离(当为奇数的时候,向左和下倾斜),做矩形,然后分别判断,上下左右,在不在(n,m)内,如果下不在,则往上移,一直到下为0,依次搞定其他个方向。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<queue>
#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;
}