夹角有多大II
这次xhd面临的问题是这样的:在一个平面内有两个点,求两个点分别和原点的连线的夹角的大小。
注:夹角的范围[0,180],两个点不会在圆心出现。
Input
输入数据的第一行是一个数据T,表示有T组数据。
每组数据有四个实数x1,y1,x2,y2分别表示两个点的坐标,这些实数的范围是[-10000,10000]。
Output
对于每组输入数据,输出夹角的大小精确到小数点后两位。
Sample Input
2
1 1 2 2
1 1 1 0
Sample Output
0.00
45.00
解题思路:
跟编程没什么关系,用数学知识。拿数量积算夹角。
#include<stdio.h>
#include<math.h>
#define PI acos(-1.0)
int main()
{
double x1,y1,x2,y2,ans;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
ans=acos((x1*x2+y1*y2)/(sqrt(x1*x1+y1*y1)*sqrt(x2*x2+y2*y2)))*180/PI;
printf("%.2lf\n",ans);
}
return 0;
}
整数解
有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,它们到底是真还是假,也就是这种整数到底存不存在,实在有点吃不准,你能快速回答吗?看来只能通过编程。
例如:
x + y = 9,x * y = 15 ? 找不到这样的整数x和y
1+4=5,1*4=4,所以,加起来等于5,乘起来等于4的二个整数为1和4
7+(-8)=-1,7*(-8)=-56,所以,加起来等于-1,乘起来等于-56的二个整数为7和-8
Input
输入数据为成对出现的整数n,m(-10000<=n,m<=10000),它们分别表示整数的和与积,如果两者都为0,则输入结束。
Output
只需要对于每个n和m,输出“Yes”或者“No”,明确有还是没有这种整数就行了。
Sample Input
9 15
5 4
1 -56
0 0
Sample Output
No
Yes
Yes
解题思路:
用数学公式算出来x和y。再判断x和y是不是整数。如果是整数double x应该等于(int)x。
#include<stdio.h>
#include<math.h>
int main()
{
double n,m,x,y;
while(1)
{
scanf("%lf%lf",&n,&m);
if(n==0&&m==0) return 0;
x=1.0*(n+sqrt(n*n-4*m))/2;
y=1.0*(n-sqrt(n*n-4*m))/2;
if(x==(int)x&&y==(int)y)
printf("Yes\n");
else
printf("No\n");
}
}
亲和数
古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:
1+2+4+5+10+11+20+22+44+55+110=284。
而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
你的任务就编写一个程序,判断给定的两个数是否是亲和数
Input
输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000 ;
Output
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。
Sample Input
2
220 284
100 200
Sample Output
YES
NO
解题思路:
先求出a的真约数和,判断是否和b相等,如果相等再进一步求b的真约数和并判断。
#include<stdio.h>
int main()
{
int t,a,b,sum1,sum2;
scanf("%d",&t);
while(t--)
{
sum1=0;
sum2=0;
scanf("%d%d",&a,&b);
for(int i=1;i<a;i++)
{
if(a%i==0)
sum1+=i;
}
if(sum1==b)
{
for(int i=1;i<b;i++)
{
if(b%i==0)
sum2+=i;
}
if(sum2==a)
printf("YES\n");
else
printf("NO\n");
}
else
printf("NO\n");
}
}
人见人爱A+B
HDOJ上面已经有10来道A+B的题目了,相信这些题目曾经是大家的最爱,希望今天的这个A+B能给大家带来好运,也希望这个题目能唤起大家对ACM曾经的热爱。
这个题目的A和B不是简单的整数,而是两个时间,A和B 都是由3个整数组成,分别表示时分秒,比如,假设A为34 45 56,就表示A所表示的时间是34小时 45分钟 56秒。
Input
输入数据有多行组成,首先是一个整数N,表示测试实例的个数,然后是N行数据,每行有6个整数AH,AM,AS,BH,BM,BS,分别表示时间A和B所对应的时分秒。题目保证所有的数据合法。
Output
对于每个测试实例,输出A+B,每个输出结果也是由时分秒3部分组成,同时也要满足时间的规则(即:分和秒的取值范围在0~59),每个输出占一行,并且所有的部分都可以用32位整数表示。
Sample Input
2
1 2 3 4 5 6
34 45 56 12 23 34
Sample Output
5 7 9
47 9 30
解题思路:
相当于写一个60进制的加法运算。注意取模和保留进位就可以了。
#include<stdio.h>
int main()
{
int t,a1,a2,a3,b1,b2,b3,c1,c2,c3;
scanf("%d",&t);
while(t--)
{
c1=0;
c2=0;
c3=0;
scanf("%d%d%d%d%d%d",&a1,&a2,&a3,&b1,&b2,&b3);
c3=(a3+b3)%60;
c2=((a3+b3)/60+a2+b2)%60;
c1=((a3+b3)/60+a2+b2)/60+a1+b1;
printf("%d %d %d\n",c1,c2,c3);
}
}
不容易系列之二
解题思路:
纯水题,逆推就可以了。
#include<stdio.h>
int main()
{
int t,a,ans;
scanf("%d",&t);
while(t--)
{
ans=3;
scanf("%d",&a);
for(int i=1;i<=a;i++)
{
ans=(ans-1)*2;
}
printf("%d\n",ans);
}
}
Switch Game
There are many lamps in a line. All of them are off at first. A series of operations are carried out on these lamps. On the i-th operation, the lamps whose numbers are the multiple of i change the condition ( on to off and off to on ).
Input
Each test case contains only a number n ( 0< n<= 10^5) in a line.
Output
Output the condition of the n-th lamp after infinity operations ( 0 - off, 1 - on ).
Sample Input
1
5
Sample Output
1
0
解题思路:
求出n的所有因数(包括1和n)的个数,如果是奇数个输出1,偶数个输出0。
#include<stdio.h>
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum=0;
for(int i=1;i<=n;i++)
{
if(n%i==0)
sum++;
}
if(sum%2==0)
printf("0\n");
else
printf("1\n");
}
}
人见人爱A^B
求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”
Input
输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。
Output
对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。
Sample Input
2 3
12 6
6789 10000
0 0
Sample Output
8
984
1
解题思路:
一直%1000,只保留最后三位数,否则肯定会超出int型的范围。
#include<stdio.h>
int main()
{
int a,b,ans;
while(1)
{
scanf("%d%d",&a,&b);
if(a==0&&b==0) return 0;
ans=a;
a=a%1000;
b--;
while(b--)
{
ans=ans%1000;
ans=ans*a;
}
printf("%d\n",ans%1000);
}
}