10.5 广州集训 Day4

Posted drizzly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>
  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的主要内容,如果未能解决你的问题,请参考以下文章

北京集训DAY4

SD 一轮集训 day4 圣城鼠

CDQZ集训DAY4 日记

长沙集训day4(总结)(爆零记)

SD 一轮集训 day4 弦形袋鼠

「6月雅礼集训 2017 Day4」暴力大神hxx