C
题意:给你一堆不同的点,从中选三个点,能够获得的三角形个数有多少
方法:选三个点,判断是否三点共线,或者用海伦公式判断面积是否为0
#include<iostream>
#include<string>
#include<vector>
using namespace std;
#define int long long
vector<pair<int, int>> v;
int n;
signed main(){
cin >> n;
for(int i = 0; i < n; i ++){
int a, b;
cin >> a >> b;
v.push_back({a, b});
}
int res = 0;
for(int i = 0; i < n; i ++)
for(int j = i + 1; j < n; j ++)
for(int k = j + 1; k < n; k ++){
int dx0 = v[j].first - v[i].first;
int dy0 = v[j].second - v[i].second;
int dx1 = v[k].first - v[j].first;
int dy1 = v[k].second - v[j].second;
if(dx0 * dy1 != dy0 * dx1) res ++;
}
cout << res << endl;
return 0;
}
D
题意:无向图上的八数码问题
#include<iostream>
#include<string>
#include<vector>
#include<unordered_map>
#include<queue>
using namespace std;
#define int long long
unordered_map<string, int> st;
int m;
vector<int> h[10];
queue<string> q;
signed main(){
cin >> m;
while(m --){
int a, b;
cin >> a >> b;
a --, b --;
h[a].push_back(b);
h[b].push_back(a);
}
string s(9, '0');
for(int i = 1; i <= 8; i ++){
int a;
cin >> a;
a --;
s[a] = '0' + i;
}
q.push(s);
st[s] = 1;
if(s == "123456780"){
puts("0");
return 0;
}
while(q.size()){
auto s = q.front();
q.pop();
int e = s.find('0');
for(int i = 0; i < h[e].size(); i ++){
int j = h[e][i];
string ns = s;
swap(ns[j], ns[e]);
if(st[ns]) continue;
st[ns] = st[s] + 1;
q.push(ns);
if(ns == "123456780"){
cout << st[ns] - 1 << endl;
return 0;
}
}
}
cout << -1 << endl;
}
E
题意:给你一个网格g,g中有N个点上写了数字,第i个点可以向第j个点走需要满足
- \(r_i = r_j\or c_i = c_j\)
- \(A_i < A_j\)
输出从每一个点出发,最多能走的步数
方法:dp
状态:\(f(i)\)表示从第i个点出发能走的最多步数
状态计算:\(f(i) = max(f(j) + 1),(r_i = r_j\or c_i = c_j)\and A_i < A_j\)
初始条件:f[1~n] = 0
可以用记忆化,如果用dp,就需要先根据a值升序排序,并且还需要保存每个点的位置,然后倒着转移,此时复杂度为\(O(n^2)\),N最大为1e5过不了
优化:将所有的点按照a值分成几批,然后根据a值从大到小进行状态转移,维护cmax和rmax,cmax[c]和rmax[r]分别表示第c列上能够转移的最大步数,和第r行上能够转移的最大步数(因为是按照a值从大到小做的,所以如果第r行上有值,就一定是可以转移到的),此时状态转移为\(f(i) = max\{cmax[point[i].c], rmax(point[i].r))\}\)
并且每一次更新完f(i)还需要更新
\[cmax[point[i].c] = max\{cmax[point[i].c], f(i) + 1\}\\ rmax[point[i].r] = max\{rmax[point[i].r], f(i) + 1\} \]#include<iostream>
#include<map>
#include<vector>
using namespace std;
int h, w, n;
const int N = 2e5 + 10;
struct node{
int r, c;
int i;
};
map<int, vector<node>> m;
int rmax[N], cmax[N];
int f[N];
int main(){
cin >> h >> w >> n;
for(int i = 1; i <= n; i ++){
int r, c, a;
cin >> r >> c >> a;
m[a].push_back({r, c, i});
}
for(auto it = m.rbegin(); it != m.rend(); it ++){
for(auto t : it->second) f[t.i] = max(cmax[t.c], rmax[t.r]);
for(auto t : it->second){
cmax[t.c] = max(cmax[t.c], f[t.i] + 1);
rmax[t.r] = max(rmax[t.r], f[t.i] + 1);
}
}
for(int i = 1; i <= n; i ++) cout << f[i] << endl;
}