1. 程式人生 > >10.5 廣州集訓 Day4

10.5 廣州集訓 Day4

希望 pac eof als ostream res back 精度 ont

//為了方便復習先貼上來... 但是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>
  3
#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 }
std

【問題背景】
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