10.5 廣州集訓 Day4
//為了方便復習先貼上來... 但是NOIP 考前大概沒時間訂正惹 所以都是留坑T T
搖
【問題背景】
zhx喜歡玩微信搖一搖,著名科學家hys做了一個搖一搖的程序。
【問題描述】
微信搖一搖的原理是,在同一時刻(1s 內)使用搖一搖功能的所用用戶,會進入一個名單,系統給每個人返回名單裏地理意義上,離你最近的一個(或並列的多個)人。我們假設在某一時刻有 N 個人同時搖動他們的手機,每個人的名字為 Name[i](長度不超過 10,由小寫字母組成且無重名)。由於定位服務的精度問 題,第 i 個人的地理坐標只能用兩個整數 x[i]和 y[i]粗略的表示(不會有兩人在同一個位置),而地理意義的最近表示的是兩點之間的直線距離(歐幾裏得距離) 最短。系統能依次返回每個人配對的對象以及他們之間的距離。 hys 是個忙碌的科學家,你能幫他實現這個小功能嗎?
【輸入格式】
輸入文件第一行為一個整數 N,此後 N 行,每行先是兩個整數 x[i]、y[i],然後是一個字符串 Name[i],互相之間用空格隔開。
【輸出格式】
共 N 行,每行先輸出最近距離,保留兩位小數(四舍五入),此後輸出離第 i 個人最近的人的名字,若有多個,按字典序從小到大依次輸出,中間用空格隔開。
【樣例輸入】
3
3 0 alice
0 7 bob
-3 0 kitty
【樣例輸出】
6.00 kitty
7.62 alice kitty
6.00 alice
【數據規模與約定】
對於40%的數據,滿足2≤??≤10000。
對於100%的數據, 滿足2≤??≤5?10^5,0≤|??i|,|yi|≤1800。
Solution:
留坑
1 #include <cassert> 2 #include <cctype> 3std#include <cstdlib> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <ctime> 8 #include <string> 9 #include <complex> 10 #include <numeric> 11 #include <algorithm> 12 #include <functional> 13 #include <utility> 14#include <vector> 15 #include <stack> 16 #include <queue> 17 #include <deque> 18 #include <bitset> 19 #include <set> 20 #include <map> 21 #include <iterator> 22 #include <iostream> 23 #include <iomanip> 24 #include <sstream> 25 #include <fstream> 26 27 using namespace std; 28 29 const int dx[] = {-1, -1, 1, 1}; 30 const int dy[] = {1, -1, -1, 1}; 31 const int MaxN = 600000; 32 const int MaxM = 4500; 33 const int inf = 1e9; 34 const int OFFSET = 2000; 35 const int THRESHOLD = 5000; 36 typedef complex<int> cpi; 37 38 int n; 39 int x[MaxN], y[MaxN]; 40 char name[MaxN][20]; 41 int grid[MaxM][MaxM]; 42 int vis[MaxM][MaxM]; 43 cpi tc[MaxM*MaxM]; 44 int n_tc; 45 cpi heap[MaxN*64]; 46 int size; 47 int ans[MaxN], ans_size, ans_dis; 48 bool found[MaxN]; 49 50 bool cmp(const cpi &x, const cpi &y) { 51 return norm(x) > norm(y); 52 } 53 bool namecmp(const int &x, const int &y) { 54 return strcmp(name[x], name[y]) < 0; 55 } 56 int dis(int a, int b) { 57 return (x[a]-x[b])*(x[a]-x[b]) + (y[a]-y[b])*(y[a]-y[b]); 58 } 59 60 int main(void) { 61 // freopen("imes.in", "r", stdin); 62 // freopen("imes.out", "w", stdout); 63 64 scanf("%d", &n); 65 for (int i = 1; i <= n; ++i) { 66 scanf("\n%d %d %s", x+i, y+i, name[i]); 67 grid[x[i]+OFFSET][y[i]+OFFSET] = i; 68 } 69 if (n <= THRESHOLD) { 70 for (int i = 1, tmp; i <= n; ++i) { 71 ans_size = 0, ans_dis = inf; 72 for (int j = 1; j <= n; ++j) 73 if (i != j) { 74 tmp = dis(i, j); 75 if (tmp < ans_dis) 76 ans[0] = j, ans_size = 1, ans_dis = tmp; 77 else if (tmp == ans_dis) 78 ans[ans_size++] = j; 79 } 80 sort(ans, ans+ans_size, namecmp); 81 printf("%.2lf", sqrt(double(ans_dis))); 82 for (int j = 0; j < ans_size; ++j) 83 printf(" %s", name[ans[j]]); 84 puts(""); 85 } 86 } else { 87 int __count = 0; 88 for (int i = 1; i <= n; ++i) { 89 for (int j = 0; j < n_tc; ++j) { 90 vis[real(tc[j])][imag(tc[j])] = false; 91 } 92 for (int j = 0; j < ans_size; ++j) 93 found[ans[j]] = false; 94 n_tc = 0; 95 96 size = 0; 97 heap[size++] = cpi(0, 1), heap[size++] = cpi(1, 0); 98 99 int _x = x[i], _y = y[i]; 100 ans_size = 0, ans_dis = inf; 101 while (ans_dis == inf || norm(heap[0]) == ans_dis) { 102 cpi cur = heap[0]; pop_heap(heap, heap+size, cmp); --size; 103 104 for (int k = 0; k < 4; ++k) { 105 int _nx = _x+dx[k]*real(cur), _ny = _y+dy[k]*imag(cur); 106 if (_nx < -OFFSET || _nx > OFFSET || _ny < -OFFSET || _ny > OFFSET) 107 continue; 108 if (grid[_nx+OFFSET][_ny+OFFSET]) { 109 if (ans_dis == inf) 110 ans_dis = norm(cur); 111 if (ans_dis == norm(cur) && !found[grid[_nx+OFFSET][_ny+OFFSET]]) { 112 ans[ans_size++] = grid[_nx+OFFSET][_ny+OFFSET]; 113 found[grid[_nx+OFFSET][_ny+OFFSET]] = true; 114 } 115 } 116 } 117 if (!vis[real(cur)+1][imag(cur)]) heap[size++] = cpi(real(cur)+1, imag(cur)), tc[n_tc++] = heap[size-1], push_heap(heap, heap+size, cmp), vis[real(cur)+1][imag(cur)] = true; 118 if (!vis[real(cur)][imag(cur)+1]) heap[size++] = cpi(real(cur), imag(cur)+1), tc[n_tc++] = heap[size-1], push_heap(heap, heap+size, cmp), vis[real(cur)][imag(cur)+1] = true; 119 __count+=2; 120 } 121 sort(ans, ans+ans_size, namecmp); 122 printf("%.2lf", sqrt(double(ans_dis))); 123 for (int j = 0; j < ans_size; ++j) 124 printf(" %s", name[ans[j]]); 125 puts(""); 126 } 127 // printf("%d\n", __count); 128 } 129 130 return 0; 131 }
變
【問題背景】
zhx和他的妹子玩一個數字遊戲。
【問題描述】
zhx手上有 N 個數??3,和另外兩個數??和??,滿足??>??。
現在,你需要做一 個遊戲。遊戲中的每一輪中,你可以做如下兩種操作之一:
1. 執行??=???1。
2. 選擇一個 1 到 N 之間的數 x,執行: ??=???(?? ?????? ??x)
zhx 和他的妹子玩遊戲去了,現在,zhx 希望聰明的你告訴他,至少通過多少輪操作,可以使得??= ??。
【輸入格式】
第一行一個整數 N。
接下來一行 N 個整數??i。
最後一行兩個整數??,??。
【輸出格式】
僅一行,包含最少的操作論數
。
【樣例輸入1】
3
1 2 3
5 2
【樣例輸出1】
2
【樣例輸入2】
0
5 2
【樣例輸出2】
3
【數據規模與約定】
對於30%的數據,滿足1≤??≤1000,??≤1000。
對於50%的數據,滿足1≤??≤1000,??≤10000。
對於100%的數據, 滿足1≤??≤100,0<??<??≤10^7,0<??i≤10^7。
Solution:
留坑。
1 //澶存枃浠秢{{ 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<time.h> 6 #include<math.h> 7 #include<algorithm> 8 #include<string> 9 #include<queue> 10 #include<vector> 11 #include<map> 12 #include<set> 13 #include<complex> 14 using namespace std; 15 16 const int inf=0x0f0f0f0f; 17 18 #define uset unordered_set 19 #define umap unordered_map 20 #define pqueue priority_queue 21 22 typedef long long ll; 23 24 typedef pair<int,int> pii; 25 typedef pair<ll,ll> pll; 26 27 typedef complex<double> point; 28 29 typedef vector<int> vint; 30 31 #define pb push_back 32 33 //template<class S,class T> inline pair<S,T> mp(S a,T b){return make_pair(a,b);} 34 #define mp make_pair 35 //template<class S,class T> inline S& LX(pair<S,T> &X){return X.first;} 36 //template<class S,class T> inline const S& LX(const pair<S,T> &X){return X.first;} 37 //template<class S,class T> inline T& RX(pair<S,T> &X){return X.second;} 38 //template<class S,class T> inline const T& RX(const pair<S,T> &X){return X.second;} 39 #define fst first 40 #define snd second 41 42 template<class T> inline void rst(T &a){memset(a,0,sizeof(a));} 43 template<class T> inline void rst1(T &a){memset(a,-1,sizeof(a));} 44 template<class T> inline void sinf(T &a){memset(a,0x0f,sizeof(a));} 45 template<class S,class T> inline void rst(S &a,T b){fill((T*)a,(T*)a+(sizeof(a)/sizeof(b)),b);} 46 template<class T> inline void clr(T &a){a.clear();} 47 template<class S,class T> inline void cpy(S &a,T &b){memcpy(a,b,sizeof(a));} 48 template<class S,class T> inline bool chkmin(S &a,T b){return b<a?a=b,1:0;} 49 template<class S,class T> inline bool chkmax(S &a,T b){return a<b?a=b,1:0;} 50 template<class T> inline T sqr(T x){return x*x;} 51 //template<class T> inline int sz(T &a){return (int)(a.size());} 52 #define sz size 53 //template<class T> inline bool ept(T &a){return a.empty();} 54 #define ept empty 55 //}}} 56 int n; 57 set<int> X; 58 typedef set<int>::iterator iter; 59 int a,b; 60 int noob[100010]; 61 int main(){ 62 scanf("%d",&n); 63 for(int i=1;i<=n;i++){ 64 int x; 65 scanf("%d",&x); 66 X.insert(x); 67 } 68 scanf("%d%d",&a,&b); 69 int ans=0; 70 while(a>b){ 71 int na=a-1; 72 int c=0; 73 for(iter i=X.begin();i!=X.end();++i){ 74 int x=*i; 75 int t=a-a%x; 76 if(t<b)noob[c++]=x; 77 else chkmin(na,t); 78 } 79 for(int i=0;i<c;i++)X.erase(noob[i]); 80 ans++; 81 a=na; 82 } 83 printf("%d\n",ans); 84 return 0; 85 }std
搞
【問題背景】
zhx有很多小弟,他突然要搞事情。
【問題描述】
zhx 有很多小弟,編號 2-N(zhx 的編號為 1)。除了 zhx 自己之外,每個人都有一個直接上司,任何消息只能經由一個人的上司傳達到他。現在你需要選出一些人(包括 zhx)完成一項任務。除此之外,你需要確定一個人 M(可以不是 被選出的人)作為管理者,且滿足他能夠給選出的所有人發送指令(直接或間接, 在發送消息時,任何人不管有沒有被選出都能幫助傳遞消息)。 已知讓第 i 個人工作需要的薪水為a5,且第 i 個人作為管理者時帶來的加成為 b5。假設一共選出了 K 個人,且管理者是 M,那麽這個團隊的戰鬥力是K?bI。 現在你希望在選出的人的薪水總和小於等於 C 的情況下,最大化這個戰鬥力。
【輸入格式】
第一行兩個整數 N,C。
接下來 N 個每行 3 個整數?? 3,??3,??3,f5表示第 i 個人的上司的編號,a, b 如題意所述 。
輸入保證 1 號(zhx)的上司為 0。
【輸出格式】
僅一行,可以達到的最大戰鬥力。
【樣例輸入】
5 4
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1
【樣例輸出】
6
【樣例解釋】
選擇 zhx 作為管理者,選擇 3,4 號完成任務。
【數據規模與約定】
對於10%的數據,滿足1≤ ?? ≤10。
對於40%的數據,滿足1≤ ?? ≤10000。
對於100%的數據, 滿足1≤ ?? ≤10^5, 0≤??i≤??, 0≤??i,??i,??≤10^9
Solution:
留坑。
1 #include <cstdlib> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 8 typedef long long i64; 9 10 struct vector { 11 vector(void) { 12 v = new int[16]; 13 sz = 0, cap = 16; 14 } 15 void push_back(int x) { 16 if (sz >= cap) realloc(cap * 2); 17 v[sz++] = x; 18 } 19 int pop_back(void) { 20 int ret = v[--sz]; 21 if (sz <= cap / 4 && cap / 2 >= 16) realloc(cap / 2); 22 return ret; 23 } 24 int size(void) { return sz; } 25 int *begin(void) { return v; } 26 int *end(void) { return v + sz; } 27 void realloc(int new_cap) { 28 int *v2 = new int[new_cap]; 29 memcpy(v2, v, sz * sizeof(int)); 30 delete []v; v = v2; 31 cap = new_cap; 32 } 33 int *v, sz, cap; 34 }; 35 36 struct pq { 37 pq(void) {} 38 void push(int x) { 39 v.push_back(x); 40 std::push_heap(v.begin(), v.end()); 41 } 42 int pop() { 43 std::pop_heap(v.begin(), v.end()); 44 return v.pop_back(); 45 } 46 int size() { return v.size(); } 47 vector v; 48 }; 49 50 using std::swap; 51 using std::max; 52 53 const int MaxN = 100005; 54 55 i64 ans; 56 int n, m; 57 int c[MaxN], l[MaxN]; 58 59 struct edge_t { 60 edge_t *next; 61 int a, b; 62 } edges[MaxN]; 63 int nr_edges; 64 65 edge_t *lk[MaxN]; 66 67 void insedge(int a, int b) { 68 edge_t *e = edges + (++nr_edges); 69 e->a = a, e->b = b; 70 e->next = lk[a], lk[a] = e; 71 } 72 73 pq heap[MaxN]; 74 75 void merge(int x, int y) { 76 if (heap[x].size() < heap[y].size()) { 77 swap(heap[x], heap[y]); 78 } 79 80 while (heap[y].size()) { 81 heap[x].push(heap[y].pop()); 82 } 83 } 84 85 int size[MaxN]; 86 i64 sum[MaxN]; 87 88 void dfs(int x) { 89 heap[x].push(c[x]); 90 size[x] = 1, sum[x] = c[x]; 91 for (edge_t *e = lk[x]; e; e = e->next) { 92 dfs(e->b); 93 size[x] += size[e->b], sum[x] += sum[e->b]; 94 merge(x, e->b); 95 } 96 while (sum[x] > m) { 97 size[x]--, sum[x] -= heap[x].pop(); 98 } 99 ans = max(ans, i64(size[x]) * l[x]); 100 } 101 102 int main(void) { 103 freopen("gao.in", "r", stdin); 104 freopen("gao.out", "w", stdout); 105 106 scanf("%d%d", &n, &m); 107 for (int i = 1; i <= n; ++i) { 108 int t; scanf("%d%d%d", &t, c+i, l+i); 109 insedge(t, i); 110 } 111 dfs(1); 112 printf("%lld\n", ans); 113 114 return 0; 115 }std
10.5 廣州集訓 Day4