Segment
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 18 Accepted Submission(s) : 14
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
They are N segments in x-axis. Each segment has a start point X, an end point Y, so it can be expressed as [X, Y].
Now you should select two segments, and they have the longest overlap length.
For example, segment [3, 10] and segment [7, 12] overlap in [7, 10], so the length is 3.
Now you should select two segments, and they have the longest overlap length.
For example, segment [3, 10] and segment [7, 12] overlap in [7, 10], so the length is 3.
Input
The first line is case number T ( T <= 10 ).
For each case, the first line is the segment number N ( 1 <= N <= 100,000 ). Following there are N lines, and each line contians Xi and Yi. ( 0 <= Xi < Yi < 100,000 )
For each case, the first line is the segment number N ( 1 <= N <= 100,000 ). Following there are N lines, and each line contians Xi and Yi. ( 0 <= Xi < Yi < 100,000 )
Output
The longest overlap length of any two segments.
Sample Input
1 5 1 5 2 4 2 8 3 7 7 9
Sample Output
4
思路:贪心,先按左区间排,然后一直往后找就可以了,复杂度O(n);
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) const int N = 100005; int t, n; struct Seg { int l, r; }s[N]; void init() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d%d", &s[i].l, &s[i].r); } bool cmp(Seg a, Seg b) { return a.l < b.l; } int solve() { sort(s, s + n, cmp); int ans = 0, rv = s[0].r; for (int i = 1; i < n; i++) { if (s[i].r > rv) { ans = max(ans, rv - s[i].l); rv = s[i].r; } else ans = max(ans, s[i].r - s[i].l); } return ans; } int main() { scanf("%d", &t); while (t--) { init(); printf("%d\n", solve()); } return 0; }
Nine
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 15 Accepted Submission(s) : 4
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Randall Munroe from xkcd.com pointed out that 9 is the most rarely used key on a microwave. Let‘s all share the load.
Given a desired cooking time, find a sequence of keys with the greatest number of 9‘s such that the resulting time has less than 10% error compared to the desired cooking time. In other words, if T is the desired cooking time in seconds, and T9 is the cooking time specified by the found sequence, then 10|T - T9| < T. If there are multiple possibilities, choose the one that has the smallest error (in magnitude). If there are still ties, choose the one that is lexicographically smallest.
For example, for T = 01:15, the times 00:68-00:82 and 1:08-1:22 have less than 10% error. Of these, 00:69, 00:79, 01:09, and 01:19 have the greatest number of 9‘s, and the ones with the smallest error are 00:79 and 01:19. The lexicographically smaller of these is 00:79.
Given a desired cooking time, find a sequence of keys with the greatest number of 9‘s such that the resulting time has less than 10% error compared to the desired cooking time. In other words, if T is the desired cooking time in seconds, and T9 is the cooking time specified by the found sequence, then 10|T - T9| < T. If there are multiple possibilities, choose the one that has the smallest error (in magnitude). If there are still ties, choose the one that is lexicographically smallest.
For example, for T = 01:15, the times 00:68-00:82 and 1:08-1:22 have less than 10% error. Of these, 00:69, 00:79, 01:09, and 01:19 have the greatest number of 9‘s, and the ones with the smallest error are 00:79 and 01:19. The lexicographically smaller of these is 00:79.
Input
The input consists of a number of cases. For each case, the desired cooking time in MM:SS format is specified on one line. Each M or S can be any digit from 0 to 9. The end of input is indicated by 00:00.
Output
For each case, output on a single line the four keys to use as input to the microwave, in MM:SS format.
Sample Input
00:30 01:00 02:00 91:30 46:03 00:00
Sample Output
00:29 00:59 01:59 90:99 49:99
题意:给定一个时间,找出误差时间在10%以内, 9最多, 误差时间最少, 字典序最小的时间
思路:直接暴力4个数字找出最合适的即可。复杂度O(10^4)
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define INF 0x3f3f3f3f char str[10]; int Sum(int *num) { int sum = (num[0] * 10 + num[1]) * 60 + (num[2] * 10 + num[3]); return sum; } struct Ans { char str[5]; int num[4]; int nine; int d; }ans; void solve() { int num[4]; ans.nine = 0; ans.d = INF; memset(ans.str, 0, sizeof(ans.str)); strcpy(ans.str, "9999"); num[0] = str[0] - ‘0‘; num[1] = str[1] - ‘0‘; num[2] = str[3] - ‘0‘; num[3] = str[4] - ‘0‘; int sum = Sum(num); for (num[0] = 0; num[0] < 10; num[0]++) for (num[1] = 0; num[1] < 10; num[1]++) for (num[2] = 0; num[2] < 10; num[2]++) for (num[3] = 0; num[3] < 10; num[3]++) { int s = Sum(num); if (10 * abs(sum - s) >= sum) continue; int dd = abs(sum - s); int nine = 0; for (int i = 0; i < 4; i++) if (num[i] == 9) nine++; if (nine >= ans.nine) { if (nine == ans.nine) { if (dd <= ans.d) { if (dd == ans.d) { char ss[5]; for (int k = 0; k < 4; k++) ss[k] = num[k] + ‘0‘; ss[4] = ‘\0‘; if (strcmp(ss, ans.str) < 0) { ans.nine = nine; for (int j = 0; j < 4; j++) { ans.num[j] = num[j]; ans.str[j] = num[j] + ‘0‘; } ans.d = dd; } } else { ans.nine = nine; for (int j = 0; j < 4; j++) { ans.num[j] = num[j]; ans.str[j] = num[j] + ‘0‘; } ans.d = dd; } } } else { ans.nine = nine; for (int j = 0; j < 4; j++) { ans.num[j] = num[j]; ans.str[j] = num[j] + ‘0‘; } ans.d = dd; } } } printf("%d%d:%d%d\n", ans.num[0], ans.num[1], ans.num[2], ans.num[3]); } int main() { while (gets(str) != NULL) { if (str[0] == ‘0‘ && str[1] == ‘0‘ && str[3] == ‘0‘ && str[4] == ‘0‘) break; solve(); } return 0; }
搞笑版费马大定理
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 20 Accepted Submission(s) : 14
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
费马大定理:当n>2时,不定方程a^n+b^n=c^n没有正整数解。比如a^3+b^3=c^3没有正整数解。为了活跃气氛,我们不妨来个搞笑版:把方程改成a^3+b^3=c3,这样就有解了,比如a=4, b=9, c=79时4^3+9^3=793。
输入两个整数x, y, 求满足x<=a,b,c<=y的整数解的个数。
输入两个整数x, y, 求满足x<=a,b,c<=y的整数解的个数。
Input
输入最多包含10组数据。每组数据包含两个整数x, y(1<=x,y<=10^8)。
Output
对于每组数据,输出解的个数。
Sample Input
1 10 1 20 123 456789
Sample Output
Case 1: 0 Case 2: 2 Case 3: 16
代码:
#include <stdio.h> #include <string.h> int x, y, ans, fuck; int solve() { ans = 0; fuck = 0; for (int i = x; i * i * i <= y * 10 + 3; i++) for (int j = i; i * i * i + j * j * j <= y * 10 + 3; j++) { int sum = ((i * i * i + j * j * j) - 3); if (sum % 10) continue; sum /= 10; if (sum >=x && sum <= y) { if (x == y) fuck++; ans++; } } return ans * 2 - fuck; } int main() { int cas = 0; while (~scanf("%d%d", &x, &y)) { printf("Case %d: %d\n", ++cas, solve()); } return 0; }
Max Sum
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 62 Accepted Submission(s) : 13
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
There are N intergers make up a loop. Your job is to calculate the max sum of consecutive sub-suquence in the loop. Note, you can select a null consecutive sub-suquence.
For example, given (3, 1, -5, 2), the max sum is 2+3+1 = 6.
For example, given (3, 1, -5, 2), the max sum is 2+3+1 = 6.
Input
The first line of the input contains an integer T (1<=T<=50) which means the number of est cases. Then T lines follow, and each line starts with a number N (1<=N<=100,000), then N integers followed (all the integers are between -1,000 and 1,000).
Output
For each test case, you should output one integers, the max sum.
Sample Input
3 4 3 1 -5 2 2 -4 -1 5 3 -1 4 -4 -2
Sample Output
6 0 6
思路:单调队列去维护sum[i]最小值,sum[j] - sum[i](j - i <= n)最大的为答案,.复杂度O(n)
代码:
#include <stdio.h> #include <string.h> #include <queue> #define max(a,b) ((a)>(b)?(a):(b)) using namespace std; const int N = 200005; int t, n, num[N]; struct Node { int sum, id; }s[N]; void init() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &num[i]); num[i + n] = num[i]; } } int solve() { int ans = 0; s[0].sum = 0; s[0].id = 0; deque<Node>Q; Q.push_front(s[0]); for (int i = 1; i <= 2 * n; i++) { s[i].sum = s[i - 1].sum + num[i]; s[i].id = i; while (!Q.empty() && Q.back().sum >= s[i].sum) {Q.pop_back();} while (!Q.empty() && s[i].id - Q.front().id > n) {Q.pop_front();} Q.push_back(s[i]); ans = max(ans, s[i].sum - Q.front().sum); } return ans; } int main() { scanf("%d", &t); while (t--) { init(); printf("%d\n", solve()); } return 0; }
Find the max Link
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 12 Accepted Submission(s) : 5
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
由N个点组成的无向图,每条边有对应的权值,保证每两点之间存在且仅存在一条路径,一条路径的权值为其所有边的权值之和,请找出一条路径,对于图中每个点至多经过一次,并且这条路径上至少有一条边,这条路径的权值最大。
Input
多组数据(至多30组),第一行两个正整数N,M(2<=N<=50000,1<=M<=50000),接下来M行,每行三个整数U,V,W(1<=U,V<=N,-100000<=W<=100000)代表在点V,W间有一条权值为W的边。
Output
每组数据输出一行,为一个整数即满足题目要求的路径权值。
Sample Input
4 3 3 1 -1 4 2 4 2 1 5
Sample Output
9
思路:树形DP,dp[u][0]代表第一大的路径,dp[u][1]代表第二大的路径,复杂度o(m)
代码:
#include <stdio.h> #include <string.h> #include <vector> #define max(a,b) ((a)>(b)?(a):(b)) #define INF 0x3f3f3f3f using namespace std; const int N = 50005; int n, m, ans, dp[N][2]; struct Node { int v, value; Node(int vv, int va) { v = vv; value = va; } }; vector<Node>g[N]; void init() { int u, v, value; ans = -INF; memset(g, 0, sizeof(g)); for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &value); ans = max(ans, value); g[u].push_back(Node(v, value)); g[v].push_back(Node(u, value)); } } void dfs(int u, int fa) { dp[u][0] = dp[u][1] = -INF; for (int i = 0; i < g[u].size(); i++) { int v = g[u][i].v, value = g[u][i].value; if (fa == v) continue; dfs(v, u); int t = 0; if (dp[v][0] > 0) t = dp[v][0]; if (dp[u][0] < t + value) { dp[u][1] = dp[u][0]; dp[u][0] = t + value; } else if (dp[u][1] < t + value) dp[u][1] = t + value; } ans = max(ans, dp[u][0]); ans = max(ans, dp[u][0] + dp[u][1]); } int main() { while (~scanf("%d%d", &n, &m)) { init(); dfs(1, 0); printf("%d\n", ans); } return 0; }
Sum
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 17 Accepted Submission(s) : 8
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Given a sequence a [1], a [2], a [3]......a[n], your job is to calculate how many sub-sequence whose summation is equal to SUM.
We define a sub-sequence of the sequence is a[i],a[i+1]...a[j-1],a[j] ( i <= j ).And the number of this sub-sequence is j-i+1.
We define a sub-sequence of the sequence is a[i],a[i+1]...a[j-1],a[j] ( i <= j ).And the number of this sub-sequence is j-i+1.
Input
The first line of the input contains an integer T (1<=T<=10) which means the number of test cases. Then T lines follow, each line starts with a number N (1<=N<=100000) and a integer sum, then N integers followed (all the integers are between 0 and 1000).
Output
For each test case, you should output one line. The line is a number about how many sub-sequences whose summation is equal to SUM.
Sample Input
3 3 2 1 1 2 3 3 1 1 2 3 0 0 0 0
Sample Output
2 1 6
思路:two pointer,注意0的情况。要记录从h开始到r有多少个前缀的0.
代码:
#include <stdio.h> #include <string.h> const int N = 100005; int t, n, sum, num[N]; void init() { scanf("%d%d", &n, &sum); for (int i = 0; i < n; i++) scanf("%d", &num[i]); } int solve() { int h = 0, r = 0, s = 0, ans = 0; while (r < n) { s += num[r]; if (s > sum) { while (s > sum) {s -= num[h++];} } if (s == sum) { int cal = 1; for (int i = h; i < r; i++) { if (num[i] == 0) cal++; else break; } ans += cal; } r++; } return ans; } int main() { scanf("%d", &t); while (t--) { init(); printf("%d\n", solve()); } return 0; }
寻找acm
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 27 Accepted Submission(s) : 13
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
作为一个acmer,应该具备团队合作能力和分析问题能力。给你一个只有a,c和m的字符串,你要依次取3个字母使之恰好为acm。
比如串
accmmmca 你可以取
12345678
ac_m____
ac__m___
ac___m__
a_cm____
a_c_m___
a_c__m__共6种。
你只要给出给你的串有多少种方案能组成acm。
比如串
accmmmca 你可以取
12345678
ac_m____
ac__m___
ac___m__
a_cm____
a_c_m___
a_c__m__共6种。
你只要给出给你的串有多少种方案能组成acm。
Input
一个只有acm3种字母的串(长度<=2000)
Output
一个整数一行,表示给你的串有多少种方案能组成acm。
Sample Input
accmmmca
Sample Output
6
代码:
#include <stdio.h> #include <string.h> const int N = 2005; const char s[4] = {"acm"}; char str[N]; long long dp[4][N]; long long DP() { int len = strlen(str + 1); for (int k = 0; k <= len; k++) dp[0][k] = 1; for (int i = 1; i <= 3; i++) { dp[i][0] = 0; for (int j = 1; j <= len; j++) { if (str[j] == s[i - 1]) { dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1]; } else { dp[i][j] = dp[i][j - 1]; } } } return dp[3][len]; } int main() { while (gets(str + 1) != NULL) { printf("%lld\n", DP()); } return 0; }
Shooting Game
Time Limit : 6000/2000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 8 Accepted Submission(s) : 4
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Fat brother and Maze are playing a kind of special (hentai) game in the playground. (Maybe it’s the OOXX game which decrypted in the last problem, who knows.) But as they don’t like using repellent while playing this kind of special (hentai) game, they really
suffer a lot from the mosquito. So they decide to use antiaircraft gun to shoot the mosquito. You can assume that the playground is a kind of three-dimensional space and there are N mosquitoes in the playground. Each of them is a kind of point in the space
which is doing the uniform linear motion. (匀速直线运动) Fat brother is standing at (0, 0, 0) and once he shoot, the mosquito who’s distance from Fat brother is no large than R will be shot down. You can assume that the area which Fat brother shoot is a kind of
a sphere with radio R and the mosquito inside this sphere will be shot down. As Fat brother hate these mosquito very much, he wants to shoot as much mosquito as he can. But as we all know, it’s tired for a man to shoot even if he is really enjoying this. So
in addition to that, Fat brother wants to shoot as less time as he can.
You can (have to) assume that Fat brother is strong enough and he don’t need to rest after shooting which means that can shoot at ANY TIME.
You can (have to) assume that Fat brother is strong enough and he don’t need to rest after shooting which means that can shoot at ANY TIME.
Input
The first line of the date is an integer T, which is the number of the text cases.
Then T cases follow, each case starts with two integers N and R which describe above.
Then N lines follow, the ith line contains six integers ax, ay, az, dx, dy, dz. It means that at time 0, the ith mosquito is at (ax, ay, az) and it’s moving direction is (dx, dy, dz) which means that after time t this mosquito will be at (ax+dx*t, ay+dy*t, ax+dz*t). You can assume that dx*dx + dy*dy+ dz*dz > 0.
1 <= T <= 20, 1 <= N <= 100000, 1 <= R <= 1000000
-1000000 <= ax, ay, az <= 1000000
-100 <= dx, dy, dz <= 100
The range of each coordinate is [-10086, 10086]
Then T cases follow, each case starts with two integers N and R which describe above.
Then N lines follow, the ith line contains six integers ax, ay, az, dx, dy, dz. It means that at time 0, the ith mosquito is at (ax, ay, az) and it’s moving direction is (dx, dy, dz) which means that after time t this mosquito will be at (ax+dx*t, ay+dy*t, ax+dz*t). You can assume that dx*dx + dy*dy+ dz*dz > 0.
1 <= T <= 20, 1 <= N <= 100000, 1 <= R <= 1000000
-1000000 <= ax, ay, az <= 1000000
-100 <= dx, dy, dz <= 100
The range of each coordinate is [-10086, 10086]
Output
For each case, output the case number first, then output two numbers A and B.
A is the number of mosquito Fat brother can shoot down.
B is the number of times Fat brother need to shoot.
A is the number of mosquito Fat brother can shoot down.
B is the number of times Fat brother need to shoot.
Sample Input
6 2 1 2 0 0 -1 0 0 -2 0 0 1 0 0 2 1 4 0 0 -1 0 0 -2 0 0 1 0 0 2 1 4 0 0 -1 0 0 1 0 0 1 0 0 2 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 1 1 0 0 0 1 0 0 3 1 -1 0 0 1 0 0 -2 0 0 1 0 0 4 0 0 -1 0 0
Sample Output
Case 1: 2 1 Case 2: 2 1 Case 3: 2 2 Case 4: 0 0 Case 5: 1 1 Case 6: 3 2
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std; const int N = 100005; struct Point { double x, y, z; double xk, yk, zk; double s, e; int vis; } p[N]; int t, n, ansn, ansc; double r; void init() { ansn = ansc = 0; memset(p, 0, sizeof(p)); scanf("%d%lf", &n, &r); for (int i = 0; i < n; i ++) { scanf("%lf%lf%lf%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z, &p[i].xk, &p[i].yk, &p[i].zk); } } bool cmp(Point a, Point b) { return a.e < b.e; } void solve() { ansn = n; for (int i = 0; i < n; i ++) { double a = p[i].xk * p[i].xk + p[i].yk * p[i].yk + p[i].zk * p[i].zk; double b = 2 * p[i].x * p[i].xk + 2 * p[i].y * p[i].yk + 2 * p[i].z * p[i].zk; double c = p[i].x * p[i].x + p[i].y * p[i].y + p[i].z * p[i].z - r * r; double dlt =b * b - 4 * a * c; if (dlt < 0) { ansn--; continue; } double k1 = (-b + sqrt(dlt)) / (2 * a); double k2 = (-b - sqrt(dlt)) / (2 * a); if (k1 < 0 && k2 < 0) { ansn--; continue; } if (k2 < k1) { if (k2 < 0) k2 = 0; p[i].s = k2; p[i].e = k1; } else { if (k1 < 0) k1 = 0; p[i].s = k1; p[i].e = k2; } p[i].vis = 1; } sort(p, p + n, cmp); double c = -1000000000; for (int ii = 0; ii < n; ii ++) { if (!p[ii].vis) continue; if (p[ii].s > c) { c = p[ii].e; ansc ++; } } } int main() { int cas = 0; scanf("%d", &t); while (t--) { init(); solve(); printf("Case %d: %d %d\n", ++cas, ansn, ansc); } return 0; }