标签:single order nal choice 好处 5* name 分享 note
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5979
按AC顺序:
Time limit 1000 ms
Memory limit 65536 kB
OS Windows
InputThere are multiple test cases.
The first line contains two integer N and D indicating the number of the points and their distance to origin. (3 <= N <= 10, 1 <= D <= 10)
The next lines contain N integers indicating the angles. The sum of the N numbers is always 360.
OutputFor each test case output one float numbers indicating the area of the convex. The printed values should have 3 digits after the decimal point.
Sample Input
4 1 90 90 90 90 6 1 60 60 60 60 60 60
Sample Output
2.000 2.598
题意概括:
给出 N 个点到中心的的距离 R 和 相邻两线的角度 a(角度和一定为360),求这个多边形面积。
解题思路:
签到题
三角形面积公式 S = 1/2 * R * R * sin( a );三角形面积和即多边形面积。
不过注意要把题目给的角度做一下转换再丢进 sin 里 a = a / pi*180,考虑精度问题,一般 pi 都通过反三角函数 acos( -1 ) 求得;
AC code:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #define LL long long 7 using namespace std; 8 const float pi = acos(-1); 9 10 int main() 11 { 12 double sum, r; 13 int N; 14 double arr; 15 int s[100]; 16 while(~scanf("%d%lf", &N, &r)){ 17 sum = 0; 18 for(int i = 0; i < N; i++){ 19 scanf("%lf", &arr); 20 //printf("%lf\n", sin(arr*pi/180)); 21 sum += (1.00/2.00)*r*r*sin(arr*pi/180); 22 } 23 //sum = pi*r*r; 24 printf("%.3f\n", sum); 25 } 26 return 0; 27 }
Time limit 1000 ms
Memory limit 65536 kB
OS Windows
InputMultiple test cases (number of test cases≤50), process till end of input.
For each case, a positive integer k (1≤k≤10^5) is given on a single line.
OutputFor each case, output:
1, if the player who starts drawing has an advantage
2, if the player who starts drawing has a disadvantage
0, if Alice‘s and Bob‘s chances are equal, no matter who starts drawing
on a single line.
Sample Input
1 2
Sample Output
0 1
题意概括:
签到题。
两个人从一个有 K 个球得盒子里取球,K个球里只有一个红球(不一定有),谁先取到红球谁胜。
每次输入 K ,判断是先取优势大(输出1)还是后取优势大(输出2),还是先取后取优势相同(输出0)。
球取出后不能放入箱子。
解题思路:
首先我们可以判断得是 后取优势大得可能性为 0,即不存在(因为无论如何后取取胜得前提都是前一个没有选中)
一开始大胆地猜测 0 的情况只有 当 K 为 1 一种,其余都是 先取有利(果断无辜WA了一发)还是要老老实实推。
然后我们模拟几次会发现 1 和 0 与 K 的奇偶性有关:
n是奇数时,先取后取的机会一样。输出0。
AC code:
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std ; 6 int main( ) 7 { 8 int N_num; 9 while(scanf("%d",&N_num)!=EOF) 10 { 11 if(N_num%2!=0) 12 puts("0"); 13 else 14 puts("1"); 15 } 16 return 0; 17 }
InputThe input contains a set of test data.The first number is one positive integer N (1≤N≤100),and then N positive integersai (1≤ aiai≤2^32 - 1) followOutputOutput one line,including an integer representing the number of ‘a‘ in the group of given numbers.
Sample Input
3 97 24929 100
Sample Output
3
题意概括:
签到题。
给 N 个数,每个数可化为32位二进制,问这些数包含多少个 a (ASCII 97)。
解题思路:
签到题。
模拟,一开始考虑了所有八位的情况(高估这道题目了),WA。
其实就是 X>>=8 地遍历一遍每个数就 OK 了。
AC code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<bitset> 5 using namespace std ; 6 #define D 256 7 #define Y 97 8 int FA(int x) 9 { 10 int now=0; 11 for(int i=0 ; i<4 ; i++) 12 { 13 if(x%D==Y) 14 now++; 15 x>>=8; 16 if(x==0) 17 break; 18 } 19 return now; 20 } 21 int main( ) 22 { 23 int n; 24 while(scanf("%d",&n)!=EOF) 25 { 26 int sum=0; 27 for(int i=0 ; i<n ; i++) 28 { 29 int a; 30 scanf("%d",&a); 31 sum+=FA(a); 32 } 33 printf("%d\n",sum); 34 35 } 36 } 37 /* 38 #include <cstdio> 39 #include <iostream> 40 #include <algorithm> 41 #include <cstring> 42 #define LL long long 43 using namespace std; 44 45 int main() 46 { 47 int N; 48 while(~scanf("%d", &N)){ 49 int ans = 0, t1, t2; 50 for(int i = 0; i < N; i++){ 51 scanf("%d", &t1); 52 // t2 = t1; 53 // printf("t22:%d\n", t2); 54 while(t1){ 55 if(t1%256 == 97) ans++; 56 t1>>=8; 57 // printf("t1: %d\n", t1); 58 // t2/=256; 59 // printf("t2: %d\n", t2); 60 } 61 } 62 printf("%d\n", ans); 63 } 64 return 0; 65 } 66 */
Given two positive integers a and b,find suitable X and Y to meet the conditions:
X+Y=a
Least Common Multiple (X, Y) =b
InputInput includes multiple sets of test data.Each test data occupies one line,including two positive integers a(1≤a≤2*10^4),b(1≤b≤10^9),and their meanings are shown in the description.Contains most of the 12W test cases.OutputFor each set of input data,output a line of two integers,representing X, Y.If you cannot find such X and Y,output one line of "No Solution"(without quotation).
Sample Input
6 8 798 10780
Sample Output
No Solution 308 490
题意概括:
“一道简单的数学问题”
给出 a b两个正整数,求解 X Y;
X Y满足:
①X+Y = a
②X Y 的最小公倍数等于 b
解题思路:
我们知道如果满足X Y 的最小公倍数等于 b
那么 X*Y = GCD(X,Y)* b;
即 X*(a-X) = GCD( X, a-X) * b;
开始的做法,暴力 X (X范围到 a),果断TL;
不过通过这个暴力发现蜜汁规律:
如果X Y是满足条件的 那么 GCD(X, Y) = GCD(a, b);
最后建东哥徒手解方程,O(1)解决这道简单的数学题。
AC code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 6 using namespace std; 7 typedef long long LL; 8 LL gcd(LL a,LL b) 9 { 10 if(b==0) return a; 11 else return gcd(b,a%b); 12 } 13 14 int main() 15 { 16 LL a,b; 17 18 while(~scanf("%lld%lld",&a,&b)) 19 { 20 LL t=gcd(a,b); 21 22 LL x=(a-sqrt(a*a-4*t*b))/2; 23 LL y=a-x; 24 // printf("x=%lld,y=%lld\n",x,y); 25 if(x*y==gcd(x,y)*b) 26 printf("%lld %lld\n",x,a-x); 27 else printf("No Solution\n"); 28 } 29 }
InputInput contains multiple sets of data.For each set of data,there are four numbers in the first line:N (1 ≤ N≤ 1000)、M(1 ≤M ≤ 10000)、X,Y(X+Y≤N ),in order to show the number of players(numbered 1toN ),the number of matches,the number of known "good players" and the number of known "bad players".In the next M lines,Each line has two numbersa, b(a≠b) ,said there is a game between a and b .The next line has X different numbers.Each number is known as a "good player" number.The last line contains Y different numbers.Each number represents a known "bad player" number.Data guarantees there will not be a player number is a good player and also a bad player.OutputIf all the people can be divided into "good players" and "bad players”, output "YES", otherwise output "NO".
Sample Input
5 4 0 0 1 3 1 4 3 5 4 5 5 4 1 0 1 3 1 4 3 5 4 5 2
Sample Output
NO YES
题意概括:
有 N 个人 M 个对立关系 , 已知 X 个人是好人(无重复), Y 个人是坏人(无重复),题目问是否能区分所有人的好坏。
解题思路:
各种奇思妙想,最后得出结论 DFS 或者 BFS 解决
对题目给出得对立关系建图,通过从一个结点(优先从有标记为好或者坏的)开始DFS或者BFS,记录奇偶性判断当前结点是好是坏。
如果有矛盾输出NO 否则YES。
AC code:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 typedef struct Edge { 7 int to, next; 8 }Edge; 9 10 const int maxn = 1010; 11 int n, m, x, y; 12 int know[maxn], vis[maxn], VAL[maxn]; 13 int cnt, head[maxn]; 14 Edge e[maxn*maxn]; 15 16 void init() { 17 cnt = 0; 18 memset(head, -1, sizeof(head)); 19 memset(know, 0, sizeof(know)); 20 memset(vis, 0, sizeof(vis)); 21 memset(VAL, 0, sizeof(VAL)); 22 } 23 24 void adde(int u, int v) { 25 e[cnt].to = v, e[cnt].next = head[u]; head[u] = cnt++; 26 27 } 28 int FA(int x) 29 { 30 return 3-x; 31 } 32 bool dfs(int u) { 33 for(int i = head[u]; ~i; i=e[i].next) { 34 int v = e[i].to; 35 if(VAL[v] == VAL[u]) return 0; 36 if(vis[v]) continue; 37 vis[v] = 1; 38 VAL[v] = FA(VAL[u]); 39 if(!dfs(v)) return 0; 40 } 41 return 1; 42 } 43 44 int main() { 45 // freopen("in", "r", stdin); 46 int u, v; 47 while(~scanf("%d%d%d%d",&n,&m,&x,&y)) { 48 init(); 49 for(int i = 0; i < m; i++) { 50 scanf("%d%d",&u,&v); 51 adde(u, v); adde(v, u); 52 know[u] = know[v] = 1; 53 } 54 for(int i = 0; i < x; i++) { 55 scanf("%d", &u); 56 VAL[u] = 1; know[u] = 1; 57 } 58 for(int i = 0; i < y; i++) { 59 scanf("%d", &u); 60 VAL[u] = 2; know[u] = 1; 61 } 62 bool flag = 0; 63 for(int i = 1; i <= n; i++) { 64 if(!know[i]) { 65 flag = 1; 66 break; 67 } 68 } 69 if(flag) { 70 puts("NO"); 71 continue; 72 } 73 for(int i = 1; i <= n; i++) { 74 if(VAL[i]) { 75 vis[i] = 1; 76 if(!dfs(i)) { 77 flag = 1; 78 break; 79 } 80 } 81 } 82 for(int i = 1; i <= n; i++) { 83 if(!VAL[i]) { 84 vis[i] = 1; 85 VAL[i] = 2; 86 if(!dfs(i)) { 87 flag = 1; 88 break; 89 } 90 } 91 } 92 for(int i = 1; i <= n; i++) { 93 if(!VAL[i]) { 94 vis[i] = 1; 95 VAL[i] = 1; 96 if(!dfs(i)) { 97 flag = 1; 98 break; 99 } 100 } 101 } 102 if(!flag) puts("YES"); 103 else puts("NO"); 104 } 105 return 0; 106 }
几组数据:
1 6 5 3 3 2 1 2 3 2 3 4 3 4 5 4 5 6 5 6 7 1 3 5 8 2 4 6 9 10 YES 11 12 5 0 4 0 13 1 2 3 4 14 15 NO 16 17 5 0 5 0 18 1 2 3 4 5 19 20 YES 21 22 6 0 4 0 23 1 2 3 4 24 25 NO 26 27 5 6 3 2 28 1 4 29 4 3 30 4 5 31 3 2 32 5 2 33 2 4 34 1 3 5 35 4 2 36 37 NO 38 39 1 0 0 0 40 41 NO 42 43 1 0 1 0 44 1 45 46 YES 47 48 1 0 0 1 49 1 50 51 YES 52 53 5 1 2 2 54 1 2 55 1 2 56 3 4 57 58 NO 59 60 5 1 2 2 61 3 4 62 1 2 63 3 4 64 65 NO 66 67 5 1 5 0 68 1 2 69 1 2 3 4 5 70 71 NO 72 73 4 3 4 0 74 1 2 75 1 4 76 3 4 77 1 2 3 4 78 79 NO 80 81 6 4 3 3 82 1 3 83 3 5 84 2 4 85 4 6 86 1 3 5 87 2 4 6 88 89 NO 90 91 !!! 92 6 4 3 3 93 1 3 94 3 5 95 2 4 96 4 6 97 1 2 5 98 2 4 6 99 100 NO 101 102 6 4 3 3 103 1 4 104 2 3 105 4 5 106 2 6 107 1 2 5 108 3 4 6 109 110 YES
InputThe first line is an integer T,meaning the number of test cases.
Then T lines follow. Each line contains one integer x.
1≤T≤10^6, 1≤x≤10^9OutputMaximum s you can get modulo 10^9+7. Note that we wants to be greatest product before modulo 10^9+7.
Sample Input
1 4
Sample Output
4
题意概括:
给一个数 N ,可以把它分解成若干个不相同的数 N = a1+a2+a3+...... ,求最大的 S = a1*a2*a3*.......
分多少个随意,也可以不分。
解题思路:
一开始以为是规律题,
后来推了无果,笔纸模拟到 11 发现一个神奇的贪心
要是乘积最大化,那可分的数越多越好。
而每一个数可分的数字数量是有规律的。
x1 = 1, s1 = 1;
x2 = 2, s2 = 2;
x3 = 3, s3 = 3;
x4 = 4, s4 = 4;
x5 = 2+3, s5 = 2*3;
x6 = 2+4 [2+(3+1)], s6 = 2*4;
x7 = 3+4 [(2+1) + (3+1)], s7 = 3*4;
x8 = 3+5 [(2+1) + (3+1+1)], s8 = 3*5;
x9 = 2+3+4, s9 = 2*3*4;
x10 = 2+3+5 [2+3+(4+1)], s10 = 2*3*5;
x11 = 2+4+5 [2+(3+1)+(4+1)], s11 = 2*4*5;
...
如何构造贪心显而易见了,参考一篇大牛的证明:
https://blog.csdn.net/qq_34374664/article/details/53466435
此题关键在于得出如何能使乘积s最大
按照以往经验,必然是取一段连续自然数能够使得乘积最大,而这段连续自然数可从2开始(为啥不从1开始?从1开始还不如将这个1给这段连续自然数的最后一个数),
于是我们可以得到形如2+3+4+...+k(k=2,3,...)的式子,而x是10^9内的任意整数,我们不可能恰好能够凑成连续自然数之和,可能会多出△x
而这个△x的值,我可以保证它的范围为0≤△x≤k,相信大于等于0还是好理解的,为什么会小于等于k呢?因为当它大于k时,原式不是可以增加一项?即2+3+4+...+k+(k+1)
那么多出来的△x怎么处理呢?显然是从后往前均摊给连续自然数中的(k-1)个数,为啥从后往前?因为若我们从前往后,总是会使连续自然数重复,不好处理
于是,在我们分配完△x之后,我们大致会得到下述两种式子:
显然,我们要计算此结果,可以借助阶乘,而阶乘中缺失的项,我们除掉就可以了,那么便会涉及除法取模,显然需要用到乘法逆元
做法讲解完毕,以下是为什么连续段乘积最大的大概证明:
简而言之,假如有一个数让你拆成两个要求积最大,肯定是拆成两个一样的,如果拆成n个,肯定就是拆成这个数/n,如果没说几个,肯定都拆成几个3就拆成几个三,剩下的拆成2.这个题要求不能一样的,所以肯定就是2,3,4这样排列了,从2开始让它变小,这样数量会最多,每次加一就是让他越来越接近。所以用前缀和记录,如果有剩余的话,肯定是从后往前逐个+1,而且剩余的那个数最多=2,3,4...最大的那个数,举个例子会发现有两种情况:1.比如2*3*4*5余下5,相等。最优就是3*4*5*7,就是每个数都加一遍,然后会剩下一个1,加给最后一个,总的来说就是 除以2,乘上t+2,(t是最后一个数的值);2.不相等,2,3,4,5,余2,最优就是2,3,5,6,就是用3的阶乘*6的阶乘除以4的阶乘,因为数量太多,不能一个一个乘,就用前缀积相除,数字太大,就要用逆元了。。然后用二分优化下。。
这题找到贪心策略后,要知道数据量大的话要用前缀积+逆元求,用前缀和优化找余数。。二分也是优化这个的
AC code:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #define LL long long 6 using namespace std; 7 const int MAXN = 1e5+5; 8 const int Mod = 1e9+7; 9 10 LL mul[MAXN], sum[MAXN]; 11 void init() 12 { 13 mul[1] = 1; 14 sum[1] = 0; 15 for(int i = 2; i < MAXN; i++){ 16 sum[i] = sum[i-1] + i; //前缀和 17 mul[i] = (i*mul[i-1])%Mod; //前缀积 18 } 19 } 20 21 LL inv(LL a, int b) //费马小定理求逆元 22 { 23 LL ans = 1; 24 while(b){ 25 if(b&1) ans = (ans*a)%Mod; 26 a = (a*a)%Mod; 27 b >>= 1; 28 } 29 return ans; 30 } 31 32 int main() 33 { 34 int t, x; 35 init(); 36 scanf("%d", &t); 37 while(t--){ 38 scanf("%d", &x); 39 if(x == 1){ 40 puts("1"); 41 continue; 42 } 43 int l = 2, r = MAXN, mid, p; 44 while(l <= r){ 45 mid = (l+r)/2; 46 if(sum[mid] <= x) p = mid, l = mid+1; 47 else r = mid-1; 48 } 49 // printf("%d\n", p); 50 int num = x - sum[p]; 51 LL ans = 0; 52 if(num == p) 53 ans = (mul[p]*inv(2, Mod-2)%Mod*(p+2))%Mod; 54 else 55 ans = (mul[p+1]*inv(mul[p+1-num], Mod-2)%Mod*mul[p-num])%Mod; 56 printf("%lld\n", ans); 57 } 58 return 0; 59 }
总结:还是太年轻,任重而道远。
标签:single order nal choice 好处 5* name 分享 note
原文地址:https://www.cnblogs.com/ymzjj/p/9865017.html