A---The King's Race
http://codeforces.com/contest/1075/problem/A
题意:
一个人在((1,1)), 一个人在((n,n)), 现在他们每次轮流走一步,问谁先到达((x,y))
思路:
每个人走到((x,y))的步数是可以直接求出的。
1 #include <bits/stdc++.h> 2 #define inf 0x3f3f3f3f 3 using namespace std; 4 typedef long long LL; 5 6 LL n; 7 LL x, y; 8 9 10 int main() 11 { 12 while(scanf("%I64d", &n) != EOF){ 13 scanf("%I64d%I64d", &x, &y); 14 LL mvwhite, mvblack; 15 mvwhite = x - 1 + y - 1; 16 mvblack = n - x + n - y; 17 18 if(mvwhite <= mvblack){ 19 printf("White "); 20 } 21 else{ 22 printf("Black "); 23 } 24 } 25 return 0; 26 }
B---Taxi drivers and Lyft
http://codeforces.com/contest/1075/problem/B
题意:
一条线上有住户和出租车司机,给定他们家的横坐标和他们的身份。一个出租车司机会接到离他家最近的所有客人,如果两个出租车司机一样近,这个客人会给横坐标小的司机。现在问所有出租车司机的客人分别是多少。
思路:
从左到右找到每个住户左边最近的出租车司机,从右到左找到每个住户右边最近的出租车司机。
对每个住户判断一下他属于哪一个出租车司机。
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <stdio.h> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long LL; 13 14 int n, m; 15 const int maxn = 2e5 + 5; 16 int house[maxn]; 17 int taxi[maxn]; 18 int lft[maxn], rig[maxn]; 19 int cnt[maxn]; 20 21 int main() 22 { 23 while(scanf("%d%d", &n, &m) != EOF){ 24 for(int i = 0; i < n + m; i++){ 25 scanf("%d", &house[i]); 26 cnt[i] = 0; 27 } 28 for(int i = 0; i < n + m; i++){ 29 scanf("%d", &taxi[i]); 30 } 31 32 int last = -1; 33 for(int i = 0; i < n + m; i++){ 34 if(taxi[i]){ 35 last = i; 36 } 37 else{ 38 lft[i] = last; 39 } 40 } 41 last = -1; 42 for(int i = n + m - 1; i >= 0; i--){ 43 if(taxi[i]){ 44 last = i; 45 } 46 else{ 47 rig[i] = last; 48 } 49 } 50 51 for(int i = 0; i < n + m; i++){ 52 if(!taxi[i]){ 53 //cout<<lft[i]<<" "<<rig[i]<<endl; 54 if(lft[i] == -1){ 55 cnt[rig[i]]++; 56 } 57 else if(rig[i] == -1){ 58 cnt[lft[i]]++; 59 } 60 else{ 61 if(house[i] - house[lft[i]] <= house[rig[i]] - house[i]){ 62 cnt[lft[i]]++; 63 } 64 else{ 65 cnt[rig[i]]++; 66 } 67 } 68 } 69 } 70 71 bool flag = false; 72 for(int i = 0; i < n + m; i++){ 73 if(taxi[i]){ 74 if(flag)printf(" "); 75 else{ 76 flag = true; 77 } 78 printf("%d", cnt[i]); 79 } 80 } 81 printf(" "); 82 } 83 return 0; 84 }
C---The Tower is Going Home
http://codeforces.com/contest/1075/problem/C
题意:
在((1,1))位置有一个象棋子。现在他要走到行数是1e9的位子。整个棋盘大小是1e9 * 1e9.棋盘中有一些横线和竖线的墙,问最少删去多少条可以让他走到行数是1e9的地方。
思路:
首先我们可以发现水平的墙中,如果他不是从1开始的,这个水平的墙就是没有用的。就不用存了。
然后对水平的墙按照x2排序,对竖直的墙也排序。
每次我们枚举要删去的竖直的墙。如果(i)要删去,那么(1~i-1)肯定也要删去。
然后我们统计一下删去了前(i)面墙之后,横着的墙里面有多少个和后面的竖着的墙有交点,有交点的这些横着的墙也是要删去的。
因为每次从左到右遍历竖着的墙的时候,被删去的横着的墙数应该是减少的。所以只用存一个变量来记录就可以了,不用每次都循环去找。
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <stdio.h> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long LL; 13 14 int n, m; 15 const int maxn = 1e5 + 5; 16 struct horizontal{ 17 int x1, x2, y; 18 }h_spell[maxn]; 19 int tot; 20 int v_spell[maxn]; 21 22 bool cmp_h(horizontal a, horizontal b) 23 { 24 return a.x2 < b.x2; 25 } 26 27 int main() 28 { 29 while(scanf("%d%d", &n, &m) != EOF){ 30 tot = 0; 31 for(int i = 1; i <= n; i++){ 32 scanf("%d", &v_spell[i]); 33 } 34 v_spell[n + 1] = 1e9; 35 sort(v_spell + 1, v_spell + n + 2); 36 37 for(int i = 0; i < m; i++){ 38 int a, b, c; 39 scanf("%d%d%d", &a, &b, &c); 40 if(a == 1){ 41 h_spell[++tot].x1 = a; 42 h_spell[tot].x2 = b; 43 h_spell[tot].y = c; 44 } 45 } 46 sort(h_spell + 1, h_spell + tot + 1, cmp_h); 47 48 int id_h = 0, ans = n + m, cnt = tot; 49 for(int i = 1; i <= n + 2; i++){ 50 while(id_h < tot && h_spell[id_h + 1].x2 < v_spell[i]){ 51 id_h++; 52 cnt--; 53 } 54 ans = min(ans, cnt + i - 1); 55 } 56 57 58 printf("%d ", ans); 59 } 60 return 0; 61 }