jrMz有两种角,第一种角都是正n边形的内角,第二种角都是正m边形的内角。jrMz想选出其中一些,某种角可以选多个或一个都不选,使得选出的所有角的度数之和恰好为360度。jrMz想知道这是否可能实现。
有多组测试数据,第一行一个整数(1≤T≤10),表示测试数据的组数。 对于每组测试数据,仅一行,两个整数n,m(3≤n,m≤100),之间有一个空格隔开。
对于每组测试数据,仅一行,一个字符串,若可能实现则为Yes,若不可能实现则为No。
3 4 8 3 10 5 8
Yes Yes No
第一组数据中,jrMz可以选择1个第一种角和2个第二种角,因为90+135+135=360。 第二组数据中,jrMz可以选择6个第一种角,因为6×60=360。 第三组数据中,jrMz无法选出一些度数之和为360度的角。
看到这题的数据范围我就笑了,当第一反应就是暴力求解,我们知道正n(n>=3)边形内角和为 180*(n-2),每个内角的角度就可以表示出来,然后两层循环遍历;
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> using namespace std; const int N=1000000+10; int a[N]; int main() { int t,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int x1=180-360/n; int x2=180-360/m;//正m边形的内角; int f=0; for(int i=0;; i++) { if(f||i*x1>360) break; for(int j=0;; j++) { if(i*x1+j*x2==360) { f=1; break; } if(j*x2>360) break;//限制条件,这样没有搜下去的必要了; } } if(f) printf("Yes\n"); else printf("No\n"); } return 0; }
不过题解好像要更简单一点:
不妨令n≤m。
如果n>6,由于所有角都大于120度且小于180度,也就是说,两个角一定不够,而三个角一定过多。因此一定无解;
当n≤6时,如果n=3或n=4或n=6,那么显然只需要正n边形的角就可以了。如果n=5,则已经有一个108度的角。若这种角:不取,则显然仅当m=6时有解;取1个,则还差360−108=252(度),但是没有一个正m边形的内角的度数是252的约数;取2个,则还差360−108×2=144(度),这恰好是正10边形的内角,取3个,则还差360−108×3=36(度),也不可能满足;取大于3个也显然不可能。
因此得到结论:当n和m中至少有一个为3或4或6时,或者当n和m中一个等于5另一个等于10时,有解,否则无解,时间复杂度为
O(T)。