7.30总结当日


集训队的招募马上就要截止了,还是有点不太稳,但要加油


7.30场地址
B题:
题意:给出一个多边形的各个定点,要求所有这些顶点能构成的三角形面积的最小值为多少?

解法:首先三个相邻的点所构成的三角形的面积最小,之后三角型面积的计算方法也是重点

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn = 2e5 + 5;
 7 ll x[maxn], y[maxn];
 8 
 9 int main() {
10     int n; scanf("%d", &n);
11     for (int i = 0; i < n; i++) {
12         scanf("%lld%lld", &x[i], &y[i]);
13     }
14     x[n] = x[0]; x[n + 1] = x[1];
15     y[n] = y[0]; y[n + 1] = y[1];
16     ll ans = 0x3fffffffffffffff;
17     for (int i = 0; i < n; i++) {
18         ll tmp1 = x[i] * y[i + 1] + x[i + 1] * y[i + 2] + x[i + 2] * y[i];
19         ll tmp2 = x[i] * y[i + 2] + x[i + 1] * y[i] + x[i + 2] * y[i + 1];
20         //三角形面积的向量计算方法,任意多边形也有类似的性质
21         if ((tmp1 - tmp2) < ans || i == 0)ans = tmp1 - tmp2;
22     }
23     printf("%lld", ans);
24     return 0;
25 }

H题:有一个网格图,这个图上面有起点和终点,另外有若干个怪兽点,这些怪兽会将距离小于等于d的人吃掉,求从起点到终点的最短路长度

解法:先从所有的M点开始跑一遍bfs,路径更新的上限是d,算出来所有不能走的点,在vis数组中进行更新,然后再跑一遍起点的bfs,看看能不能跑到终点即可

 1 #include<cstdio>
 2 #include<queue>
 3 #include<vector>
 4 using namespace std;
 5 int dir[4][2] = { 0,1,0,-1,1,0,-1,0 };
 6 struct node {
 7     int x, y, dis;
 8 };
 9 node st, ed;
10 int n, m, d, ans = -1;
11 vector<char>mp[200000 + 5];
12 vector<int>vis[200000 + 5];
13 
14 bool check(node nex) {
15     return nex.x >= 0 && nex.x < n&&nex.y >= 0 && nex.y < m;
16 }
17 
18 void bfs1() {
19     queue<node>q;
20     for(int i=0;i<n;i++)
21         for (int j = 0; j < m; j++) {
22             if (mp[i][j] == 'M') {
23                 q.push(node{ i,j,0 });
24                 vis[i][j] = 1;
25             }
26         }
27     while (!q.empty()) {
28         node now = q.front(); q.pop();
29         if (now.dis == d)continue;
30         node nex;
31         for (int i = 0; i < 4; i++){
32             nex.x = now.x + dir[i][0]; // 按照规则生成    下一个状态
33             nex.y = now.y + dir[i][1];
34             nex.dis = now.dis + 1; // 计数器加1
35             if (check(nex)&&!vis[nex.x][nex.y]){
36                 q.push(nex);
37                 vis[nex.x][nex.y] = 1; //访问标记
38             }
39         }
40     }
41 }
42 
43 void bfs2() {
44     queue<node>q;
45     q.push(node{ st.x,st.y,0 });
46     if (vis[st.x][st.y] == 1) { ans = -1; return; }
47     else vis[st.x][st.y] = 1;
48     while (!q.empty()) {
49         node now = q.front(); q.pop();
50         if (now.x == ed.x&&now.y == ed.y) { ans = now.dis; return; }
51         node nex;
52         for (int i = 0; i < 4; i++) {
53             nex.x = now.x + dir[i][0]; // 按照规则生成    下一个状态
54             nex.y = now.y + dir[i][1];
55             nex.dis = now.dis + 1; // 计数器加1
56             if (check(nex) && !vis[nex.x][nex.y]) {
57                 q.push(nex);
58                 vis[nex.x][nex.y] = 1; //访问标记
59             }
60         }
61     }
62     ans = -1;
63 }
64 
65 int main() {
66     scanf("%d%d%d", &n, &m, &d);
67     for (int i = 0; i < n; i++) {
68         vis[i].resize(m + 5); getchar();
69         for (int j = 0; j < m; j++) {
70             char c = getchar();
71             if (c == 'S')st.x = i, st.y = j;
72             if (c == 'F')ed.x = i, ed.y = j;
73             mp[i].push_back(c);
74         }
75     }
76     bfs1(); 
77     bfs2();
78     printf("%d
", ans);
79     return 0;
80 }

K题:有n个人,每个人有一个值ai,要求这个人同意的前提是他前面有ai个人已经同意了,当然你可以强制让这个人同意,给出一个要求的同意人数m,问最少需要说服多少个人

解法:二分答案,你要记住二分的关键是先假设一个答案,然后看在这个答案的基础上算出来的其他变量的情况(比如说这道题里面就是加入答案是mid的话你最多可以睡服的人数),然后在根据这个来进行判断二分的方向

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<vector>
 7 #include<queue>
 8 #include<map>
 9 #include<set>
10 #include<ctime>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int>P;
14 const int INF=0x3f3f3f3f,maxn=200005;
15 int n,m,a[maxn];
16 bool check(int k)
17 {
18     int ans=0;//ans为已经同意的人(包含说服的)
19     for(int i=1;i<=n;i++)
20     {
21         if(a[i]<=ans)ans++;//第i个人前面同意的人数已经超过了a[i],所以她也会同意
22         else if(k)ans++,k--;//否则就贪心的说服他,因为早说服肯定比晚说服好
23     }
24     return ans>=m;
25 }
26 
27 int main()
28 {
29     scanf("%d%d",&n,&m);
30     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
31     int l=0,r=m,mid,ans=m;
32     //二分答案
33     while(l<=r)
34     {
35         mid=(l+r)/2;
36         if(check(mid))r=mid-1,ans=mid;
37         else l=mid+1;
38     }
39     printf("%d
",ans);
40     return 0;
41 }

原文地址:https://www.cnblogs.com/romaLzhih/p/9489796.html