AAAAA.
** 一.题目大意**:给一个数n,找三个不同的正整数,使得它们都不能被3整除,并且三个正整数的和为n。
**二. 思路: **
1.这是构造题,用一些常用的分解方法:
(1).n不是3的倍数,先分个1,2,然后分n-3,判断n-3是否等于1或2.做个判断 n-3 >= 4 ?
(2).n是3的倍数。如果这时候再分1,2,n-3还是3的倍数。所以用1,4,n-5,n-5一定不是3的倍数,
然后判断一下n-5 >= 2 且n - 5 !=1,4;
2.如果满足条件,输出“YEs”,不满足输出“NO”。
三. 代码:
``
//#include //<iostream>
//#include //<algorithm>
using namespace std;
int main()
{
int t;
cin>>t;
while ( t -- )
{
int a;
cin>>a;
int x,y,z;
if(a % 3 == 0)
{
x = 1,y = 4, z = a - 5;
if (x != y && x != z && y != z && z >= 2)
{
cout<<"YES"<<endl;
cout<<x<<' '<<y<<' '<<z<<endl;
}
else cout<<"NO"<<endl;
}
}
else
{
x = 1,y = 2 , z = a - 3;
if(x != y && y != z && x != z && z >= 3)
{
cout<<"YES"<<endl;
cout<<x<<' '<<y<<' '<<z<<endl;
}
else cout<<"NO"<<endl;
}
}
return 0;
}
`` ``
BBBB
一.题目大意:在二维平面内,有四点a,b,o(原点),p(终点)。你需要从o点,走到p点,中途只能在以a,b为圆心,x为半径的圆内走,不得超出圆心。给定若干组a,b,p点坐标,求出每组数据下x的最小值。
二。思路:
1.分类讨论:
(1).p点在离o点较近的ab点的圆内,假设是a点离o点比较近,p在a圆内。那么我们求半径的最小值r = max(oa,pa);
为什么是max,是因为a圆一定要把o点包含进来,且a圆内要有p点,就取二者的最大值,可以同时使得a圆内有op两点。
同理,如果是b点离o点比较近,那么r = max(ob,pb);
(2) .p点在离o点比较远的ab点的圆内,假设是a点离o点比较远,b点离o点比较近。那么我们必须通过b的圆进入到a的圆,最小值r 就有 ob这种可能以及ab两圆刚好相切,r = ab/2;其次考虑pa与ao的距离关系,可能r = pa,或者 r = oa;
由于b点离o点较近,所以ob<oa,因此在最后取(最大值的)最小值时,ob可以不用考虑;
因此r = max(pb,oa,ab/2);同理 b离o比较近时,r = max(ob,ab/2,pa);
2.如果将分类讨论用代码实现?
方法1:我们之前假设过a,b谁离o点比较近。用代码表示就是 oa > ob 或者 oa < ob;在a的圆内就是 pa < pb,同理可以得出在b的圆内,pa > pb;这样我们只需要判断然后赋值就可以了。
方法2:由于我们求的是只存在于某种情况下的最小值,因此其他情况的值一定大于该最小值。所以我们把答案算四次,分别对应四种不同情况,唯一的正确的最小值会出现且被保留到最后;(不是最小值就会被更新成更小值,是最小值就不会被更新,到最后,一定是最小值)。(简单粗暴)
三.代码
** 方法1:**
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
double dist(double x1 , double y1 ,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
double maxn(double x,double y,double z)
{
double a[3] = {x,y,z};
sort(a,a+3);
return a[2];
}
int main()
{
int t;
cin>>t;
while( t -- )
{
int px,py,ax,ay,bx,by;
cin>>px>>py>>ax>>ay>>bx>>by;
double oa = dist(0,0,ax,ay) , ob = dist(0,0,bx,by);
double pa = dist(ax,ay,px,py) , pb = dist(bx,by,px,py),ab = dist(ax,ay,bx,by);
double R = 0x3f3f3f3f;
if (oa < ob)
{
if (pa < pb)printf("%.10lf\n",maxn(oa,pa,-0x3f3f3f3f));
else printf("%.10lf\n",maxn(oa,ab/2,pb));
}
else
{
if(pa > pb)printf("%.10lf\n",maxn(ob,pb,-0x3f3f3f3f));
else printf("%.10lf\n",maxn(pa,ob,ab/2));
}
}
return 0;
}
**方法2:**
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
double dist(double x1 , double y1 ,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
double maxn(double x,double y,double z)
{
double a[3] = {x,y,z};
sort(a,a+3);
return a[2];
}
int main()
{
int t;
cin>>t;
while( t -- )
{
int px,py,ax,ay,bx,by;
cin>>px>>py>>ax>>ay>>bx>>by;
double oa = dist(0,0,ax,ay) , ob = dist(0,0,bx,by);
double pa = dist(ax,ay,px,py) , pb = dist(bx,by,px,py),ab = dist(ax,ay,bx,by);
double R = 0x3f3f3f3f;
R = min(R,max(oa,pa));
R = min(R,max(ob,pb));
double bm = maxn(oa,(ab)/2,pb);
double am = maxn(ob,pa,ab/2);
R = min(R,bm);
R = min(R,am);
printf("%.10lf\n",R);
}
return 0;
}