AtCoder Beginner Contest 224 复盘
在回家的车上打的,效果挺差。
A
一遍 AC。
std::string ss;
int main() {
cin >> ss;
int n = (int) ss.size();
if (ss[n - 1] == 'r' && ss[n - 2] == 'e') cout << "er" << endl;
else cout << "ist" << endl;
return 0;
}
B
一遍 AC。
const int MAXN = 50 + 10;
int n, m, aa[MAXN][MAXN];
int main() {
n = read(); m = read();
rep (i, 1, n) rep (j, 1, m) aa[i][j] = read();
bool flag = true;
rep (i1, 1, n) rep (i2, i1 + 1, n) rep (j1, 1, m) rep (j2, j1 + 1, m) {
if (aa[i1][j1] + aa[i2][j2] <= aa[i1][j2] + aa[i2][j1]);
else flag = false;
}
if (flag) puts("Yes");
else puts("No");
return 0;
}
C. Triangle?
虽然是神必题,但是我被卡精度了,第二个样例答案一直差 2,换了题解的写法才过
const int MAXN = 300 + 10;
struct Point {
int x, y;
} ps[MAXN];
int n;
int main() {
n = read();
rep (i, 1, n) {
ps[i].x = readll(); ps[i].y = readll();
}
long long int ans = 0;
rep (i, 1, n) {
rep (j, i + 1, n) {
rep (k, j + 1, n) {
int x1 = ps[i].x, x2 = ps[j].x, x3 = ps[k].x;
int y1 = ps[i].y, y2 = ps[j].y, y3 = ps[k].y;
ans += (std::abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) > 0);
}
}
} printf("%lld\n", ans);
return 0;
}
D
挺基础的图论模型题,但是调了好久才过,原因是肌肉记忆写了个 typo
#错误警示:不要相信肌肉记忆。
const int MAXN = 9 + 2;
const int MAXS = 362880 + 10;
int m;
std::vector<int> G[MAXN];
int pow10[10];
struct Node {
int u, w;
bool operator < (const Node &th) const {
return w > th.w;
}
};
std::map<int, int> dist;
std::map<int, bool> vis;
void sp(int u) {
std::priority_queue<Node> q;
q.push({u, dist[u] = 0});
while (!q.empty()) {
int now = q.top().u; q.pop();
if (vis[now]) continue;
vis[now] = true;
// DEBUG(now);
for (int p = 0; p < 9; ++p) {
int nxt = now;
if ((now / pow10[p]) % 10 == 0) continue;
// DEBUG(p);
forall (G[p + 1], i) {
int v = G[p + 1][i];
if ((nxt / pow10[v - 1]) % 10 == 0) {
int mov = (now / pow10[p]) % 10;
nxt -= pow10[p] * mov;
nxt += mov * pow10[v - 1];
if (!dist.count(nxt)) dist[nxt] = 0x3f3f3f3f;
if (dist[nxt] > dist[now] + 1) {
// if (nxt == 87654321) DEBUG(now);
// DEBUG(v);
q.push({nxt, dist[nxt] = dist[now] + 1});
}
}
}
}
}
}
int main() {
m = read();
pow10[0] = 1;
rep (i, 1, 9) pow10[i] = pow10[i - 1] * 10;
rep (i, 1, m) {
int u = read(); int v = read();
G[u].push_back(v); G[v].push_back(u);
}
int pre_stat = 0;
for (int i = 1; i <= 8; ++i) {
int x = read();
pre_stat += pow10[x - 1] * i;
}
// DEBUG(pre_stat);
sp(pre_stat);
int finstat = 87654321;
if (!dist.count(finstat)) puts("-1");
else printf("%d\n", dist[finstat]);
return 0;
}
然后我过掉 D 题电脑就没电了。考试到此终结。
E. Integers on Grid
可以发现最终形成的图是一张 DAG,所以一个显然的做法是建图跑最长路。
但其实你甚至不用建图(因为建图挺麻烦的,需要搞个双指针),直接记搜就可以了,在 dfs 里面确定接下来要走的那个点。
而且你甚至不用记搜,换一下 DP 顺序,value 从高到低 DP,用类似前缀和优化的方法记一下每一行每一列 DP 的最大值,然后就可以常数时间转移了。
因为你需要排序,所以时间复杂度 \(O(n\log n)\) 级别的。可以用 std::map
实现。
const int MAXN = 2e5 + 10;
int h, w, n;
std::map<int, std::vector<int> > mp;
int rr[MAXN], cc[MAXN], aa[MAXN];
int dp[MAXN], rmax[MAXN], cmax[MAXN];
int main() {
h = read(); w = read(); n = read();
rep (i, 1, n) {
rr[i] = read(); cc[i] = read(); aa[i] = read();
mp[aa[i]].push_back(i);
}
for (auto it = mp.rbegin(); it != mp.rend(); it++) {
for (auto u : it->second) dp[u] = std::max(rmax[rr[u]], cmax[cc[u]]);
for (auto u : it->second) {
rmax[rr[u]] = std::max(rmax[rr[u]], dp[u] + 1);
cmax[cc[u]] = std::max(cmax[cc[u]], dp[u] + 1);
}
}
rep (i, 1, n) printf("%d\n", dp[i]);
return 0;
}
下面这个是记搜的做法,只 WA 了一个点,至今没调出来。
const int MAXN = 2e5 + 10;
int h, w, n;
struct E {
int id, w;
bool operator < (const E &th) const {
return w < th.w;
}
}; std::set<E> rows[MAXN], cols[MAXN];
int rowi[MAXN], coli[MAXN], vali[MAXN];
int dp[MAXN];
bool vis[MAXN];
int search(int u) {
if (vis[u]) return dp[u];
vis[u] = true;
int &ans = dp[u] = 0;
{
int r = rowi[u];
auto it = rows[r].find({u, vali[u]});
assert(it != rows[r].end());
++it;
while (it != rows[r].end() && it->w == vali[u]) ++it;
if (it != rows[r].end()) ans = std::max(ans, search(it->id) + 1);
}
{
int r = coli[u];
auto it = cols[r].find({u, vali[u]});
assert(it != cols[r].end());
++it;
while (it != cols[r].end() && it->w == vali[u]) ++it;
if (it != cols[r].end()) ans = std::max(ans, search(it->id) + 1);
}
return ans;
}
int main() {
h = read(); w = read(); n = read();
rep (i, 1, n) {
rowi[i] = read(); coli[i] = read(); vali[i] = read();
rows[rowi[i]].insert({i, vali[i]});
cols[coli[i]].insert({i, vali[i]});
}
rep (i, 1, n) printf("%d\n", search(i));
return 0;
}