预期难度顺序 F J < D I G < B E A < C G A: 分析可知,当且仅当Z距离某一扇门的距离比H更近时才能逃脱,否则不能逃脱。 可以对两扇门分别跑一次深度优先搜索确定Z和H谁离这扇门更近。 code: #include<bits/stdc++.h> using namespace std; const int maxn = 15; const int inf = 1e9; char G[maxn][maxn]; int vis[maxn][maxn]; struct node{ int x, y, step; }; queue<node>que; int n, m; int fx[4][2] = {1,0,-1,0,0,1,0,-1}; bool check(int x, int y){ if(x < 1 || x > n || y < 1 || y > m || G[x][y] == '#' || vis[x][y] != 0)return false; return true; } bool solve(int x, int y){ memset(vis, 0, sizeof vis); int hl = inf, zyj = inf; que.push({x,y,1}); node now; int nx, ny; while(!que.empty()){ now = que.front(); que.pop(); vis[now.x][now.y] = now.step; if(G[now.x][now.y] == 'H')hl = now.step; if(G[now.x][now.y] == 'Z')zyj = now.step; for(int i = 0 ; i < 4 ; i++){ nx = now.x + fx[i][0]; ny = now.y + fx[i][1]; if(check(nx,ny))que.push({nx,ny,now.step + 1}); } } return zyj < hl; } int main(){ cin >> n >> m; for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ cin >> G[i][j]; } } int ok = 0; for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ if(G[i][j] == '@' && solve(i,j))ok = 1; } } if(ok)cout << "give me northeast chicken rice and milk tea TOMORROW!\n"; else cout << "give me northeast chicken rice and milk tea!\n"; } B: 计算4的n到m次方累加,用快速幂优化即可暴力求得答案 code: #include<bits/stdc++.h> using namespace std; const int mod = 1e9 + 7; typedef long long ll; ll qpow(ll x, ll y){ ll res = 1; while(y){ if(y & 1) res = (res * x) % mod; y >>= 1; x = (x * x) % mod; } return res; } ll n, m; int main(){ cin >> n >> m; ll ans = 0; for(ll i = n; i <= m; ++i){ ans = (ans + qpow(4LL, i)) % mod; } cout << ans << "\n"; } C: 最短路+细节处理 code: #include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e4+5; ll dis[maxn]; struct Edge{ int to; ll w; friend bool operator < (Edge a, Edge b){ return a.w > b.w; } }; vector<Edge>g[maxn]; priority_queue<Edge>q; void dij(){ q.push((Edge){0, 0}); while(!q.empty()){ Edge now = q.top(); q.pop(); int u = now.to; if(now.w > dis[u]) continue; for(auto e : g[u]){ int v = e.to; if(dis[u] + e.w < dis[v]){ dis[v] = dis[u] + e.w; q.push((Edge){v, dis[v]}); } } } } int main(){ int n, m; cin >> n >> m; int u, v; ll w; for(int i = 1; i <= n; i++) dis[i] = 1e18; for(int i = 1; i <= m; i++){ cin >> u >> v >> w; g[u].push_back((Edge){v, w}); } dij(); ll ans = 0, mx = 0; for(int i = 1; i <= n; i++){ if(mx < dis[i]) mx = dis[i], ans = i; } cout << mx << ' ' << ans << endl; return 0; } D: 分析可知,应尽可能选择bi小的课程,所以用结构体排序。按照bi从小到大的顺序依次遍历每一门课程并且算出课程对答案的贡献。 code: #include<bits/stdc++.h> using namespace std; struct node{ int s, b, c; }a[105]; int n, r; bool cmp(node x, node y){ return x.b < y.b; } int main(){ cin >> n >> r; int sum = 0; for(int i = 1 ; i <= n; ++i){ cin >> a[i].s >> a[i].b >> a[i].c; sum += a[i].s; } sort(a + 1, a + 1 + n, cmp); int p = 0; for(int i = 1; i <= n; ++i){ int tmp = a[i].c - a[i].s; if(sum + tmp >= r){ tmp = r - sum; p += a[i].b * tmp; break; } p += tmp * a[i].b; sum += tmp; } cout << p << "\n"; } E: 将距离小于等于d的点看作是一个集合,用并查集算法讲距离小于等于d的点合并到一个集合中,最后输出所有集合的个数。 code: #include<bits/stdc++.h> using namespace std; const int mod = 1e9 + 7; typedef long long ll; const int maxn = 1e3 + 5; struct node{ int x, y; }a[maxn]; int n, d; int fa[maxn]; int find(int x){ if(fa[x] == x) return x; return fa[x] = find(fa[x]); } int main(){ cin >> n >> d; for(int i = 1; i <= n; ++i) fa[i] = i; for(int i = 1; i <= n; ++i){ cin >> a[i].x >> a[i].y; } int v, u; for(int i = 1; i <= n; ++i){ v = find(i); for(int j = i + 1; j <= n; ++j){ int tmp = (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y); if(tmp <= d * d){ u = find(j); fa[u] = v; } } } int cnt = 0; for(int i = 1; i <= n; ++i) if(fa[i] == i) cnt++; cout << cnt << "\n"; } F: 英文签到题目,输出x和y差值绝对值的一半即可。 code: #include<bits/stdc++.h> using namespace std; string s; int main(){ int n; cin >> n >> s; int x = 0, y = 0; for(int i = 0; i < s.length(); ++i){ if(s[i] == 'x') x++; else y++; } cout << abs(x - y) / 2 << "\n"; } G: 字符串模拟,可以用string自带的相等运算判断“jiuzhe“ 和 ”buhuiba“ code: #include<bits/stdc++.h> using namespace std; struct node{ string name; int s1, s2, sum; }a[6]; bool cmp(node x, node y){ return x.sum > y.sum; } int main(){ string s; a[1].name = "qh"; a[2].name = "sh"; a[3].name = "hl"; a[4].name = "xx"; a[5].name = "kt"; for(int i = 1; i <= 5; ++i){ cin >> s; for(int j = 0; j < s.length(); ++j){ string tmp = ""; if(j + 6 <= s.length()) { tmp = s.substr(j, 7); if(tmp == "buhuiba") a[i].s1++; } if(j + 5 <= s.length()) { tmp = s.substr(j, 6); if(tmp == "jiuzhe") a[i].s2++; } } a[i].sum = a[i].s1 + a[i].s2; } for(int i = 1; i <= 5; ++i){ cout << a[i].name << " " << a[i].s1 << " " << a[i].s2 << "\n"; } sort(a + 1, a + 1 + 5, cmp); if(a[1].sum == a[2].sum) cout << "yygqdss\n"; else cout << a[1].name << "\n"; } H: 要从每组五个人中选一个人,使得所有被选中的人的步子差尽可能的小。可以先不管分组,把所有人按照步子大小排序。之后只要选中连续的一个区间,使得区间中的人覆盖了1~n,就可以用这个集合中的最大步子 – 最小步子记录一个可能的答案。只要用尺取法找出所有满足这个要求的集合并比出所有答案中的最小值就是最终的答案。 code: #include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int maxn = 5e5+5; int n,k,vis[maxn]; struct node{ int val,id; bool operator < (const node & t) const{ return val < t.val; } }nd[maxn]; int main(){ cin >> n >> k; int cnt = 0; for(int i = 1;i <= n;i++){ for(int j = 0;j < 5;j++){ cin >> nd[++cnt].val; nd[cnt].id = i; } } sort(nd+1,nd+cnt+1); int l = 1,r = 1,ans = inf,flag = 0; while(r <= cnt){ while(flag != n && r <= cnt){ if(!vis[nd[r].id]){ vis[nd[r].id]++; flag++; } else{ vis[nd[r].id]++; } r++; } if(flag == n){ if((nd[r-1].val-nd[l].val) <= k) ans = min(ans,nd[r-1].val-nd[l].val); if(vis[nd[l].id] == 1){ flag--; } vis[nd[l].id]--; l++; } } if(ans == inf) cout << "-1\n"; else cout << ans << endl; return 0; } I: 按照矩阵运算的方法,分析并正确的使用循环语句和数组 code: #include<bits/stdc++.h> using namespace std; int a[205][205]; int b[205][205]; int c[205][205]; int n; int main(){ cin >> n; for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) cin >> a[i][j]; for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) cin >> b[i][j]; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j){ for(int k = 1; k <= n; ++k){ c[i][j] += a[i][k] * b[k][j]; } } } for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j){ cout << c[i][j] << " "; } cout << "\n"; } } J: 签到题:用转义字符输出字符串即可。 code: #include<stdio.h> int main(){ printf("\\(X_X)/ Says : \"I can 100%% print this !\""); }