在平面直角坐标系上有一个点P, 他的坐标是(x,y). 有一条直线y=kx+b经过了P, 且分别交x,y正半轴于A,B. 求∣PA∣∗∣PB∣的最小值.
第一行一个T, 表示数据组数. 接下来T行每行两个正整数x,y, 表示P的坐标. T=500,0<X,Y≤10000
T行,每行一个数字,表示每组数据的答案
1 2 1
4
样例中P(2,1), 取直线y=−x+3, 他经过了P并分别交x,y正半轴于A(3,0),B(0,3).∣PA∣=√2,∣PB∣=2√2,∣PA∣∣PB∣=4,经验证确实是最小值.
官方题解:
设y=kx+b与x轴负半轴的交角为α.
因为y=kx+b与x,y正半轴相交,所以α∈[0,2π).
那么∣PA∣=sinαy,∣PB∣=cosαx.
那么∣PA∣∣PB∣=sinαcosαxy=sin2α2xy.
因为sin2α≤1,所以最小值为2xy
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define LL __int64 int main() { LL t; scanf("%I64d",&t); while(t--) { LL x,y; scanf("%I64d%I64d",&x,&y); LL m=(x*y)<<1; printf("%I64d\n",m); } return 0; }
B:
tree
Accepts: 143Submissions: 807Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)问题描述有一个树(n个点, n−1条边的联通图),点标号从1~n,树的边权是0或1.求离每个点最近的点个数(包括自己).输入描述第一行一个数字T,表示T组数据. 对于每组数据,第一行是一个n,表示点个数,接下来n−1,每行三个整数u,v,w,表示一条边连接的两个点和边权. T=50,1≤n≤100000,1≤u,v≤n,0≤w≤1.输出描述对于每组数据,输出答案. 考虑到输出规模过大,设ansi表示第i个点的答案.你只需输出ans1 xor ans2 xor ans3.. xor ansn即可.输入样例1 3 1 2 0 2 3 1输出样例1Hintans1=2 ans2=2 ans3=1 2 xor 2 xor 1=1, 因此输出1.官方:把每条边权是1的边断开,发现每个点离他最近的点个数就是他所在的连通块大小.
开一个并查集,每次读到边权是0的边就合并.最后Ansi=size[findset(i)],size表示每个并查集根的size.
(我只查了他儿子,忘了查他爸,WA了12次,后来改改查他爸,AC了。。。。。。。。。。。,就一点错。。。。。。。。。。。啊啊啊
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxm=1e5+10; int u[maxm]; int v[maxm]; int w[maxm]; int p[maxm]; int num[maxm]; void Init() { for(int i=1; i<=maxm; i++) { p[i]=i; num[i]=1; } } int find(int x) { if(p[x]!=x) { p[x]=find(p[x]); } return p[x]; } int main() { int t; scanf("%d",&t); while(t--) { Init(); int n; scanf("%d",&n); for(int i=0; i<n-1; i++) { scanf("%d%d%d",&u[i],&v[i],&w[i]); int x=find(u[i]); int y=find(v[i]); if(w[i]==0) { p[y]=x; num[x]+=num[y]; } } int ans=num[find(1)]; for(int i=2; i<=n; i++) { ans^=num[find(i)]; } printf("%d\n",ans); } return 0; }