# **README**
🤑0773453956 Momo/MB
# **PRIME (YB2022)**
**Ý tưởng:** Dùng sàng nguyên tố và đảo số để kiểm tra và phân tích
```cpp
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e7;
int t,n;
bool F[maxn],C[10],kt;
int Dao(int n) {
int tmp = n%10;;
n/= 10;
while (n != 0) {
tmp = tmp*10 + (n % 10);
n/=10;
}
return tmp;
}
void Solve(int n) {
kt = false;
n = Dao(n);
C[2] = C[3] = C[5] = C[7] = false;
while (n != 0) {
if (F[n%10] && ! C[n%10]) {
kt = true;
cout << n%10 << " ";
C[n%10] = true;
}
n/=10;
}
if (kt) cout << "\n";
else cout << "0\n";
}
int main() {
freopen("PRIME.INP","r",stdin);
freopen("PRIME.OUT","w",stdout);
memset(F,true,sizeof(F));
F[0] = F[1] = false;
for (int i = 2; i <= sqrt(maxn); ++i)
if (F[i]) for (int j = i*i; j <= maxn; j+=i) F[j] = false;
cin >> t;
for (int i = 1; i <= t; ++i) {
cin >> n;
if (F[n]) cout << "YES ";
else cout << "NO ";
Solve(n);
}
return 0;
}
```
# **ROAD (YB2022)**
**Ý tưởng:** Dùng tổng tiền tố và tìm kiếm nhị phân
```cpp
#include <bits/stdc++.h>
using namespace std;
struct Road{
int val,tree;
};
Road A[300005];
int Sa[300005],Sb[300005],a,b,n,minn = INT_MAX,x;
bool cmp(Road a, Road b) {
return a.val < b.val;
}
int TKNP(int vt) {
int l = vt,r = n,tmp = -1,mid;
while (l <= r) {
mid = (l+r)/2;
if (Sa[mid] - Sa[vt-1] >= a && Sb[mid] - Sb[vt-1] >= b) {
tmp = mid;
r = mid-1;
}
else l = mid+1;
}
return tmp;
}
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
freopen("ROAD.INP","r",stdin);
freopen("ROAD.OUT","w",stdout);
cin >> n >> a >> b;
Sa[0] = Sb[0] = 0;
for (int i = 1; i <= n; ++i)
cin >> A[i].val >> A[i].tree;
sort(A+1,A+n+1,cmp);
for (int i = 1; i <= n; ++i) {
Sa[i] = Sa[i-1];
Sb[i] = Sb[i-1];
if (A[i].tree == 1) Sa[i]++;
else Sb[i]++;
}
for (int i = 1; i <= n-1; ++i) {
x = TKNP(i);
if (x != -1)
minn = min(minn,A[x].val-A[i].val);
}
if (minn == INT_MAX) cout << "-1";
else cout << minn;
return 0;
}
```
# **CONSCELL 0 Truy Vết (YB2022)**
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,m,d,maxx = INT_MIN,A[10005][10005],F[10005][10005];
int X[4] = {0,0,1,-1};
int Y[4] = {1,-1,0,0};
void DFS(int u, int v) {
F[u][v] = 1;
int k = A[u][v] + 1;
for (int i = 0; i < 4; ++i) {
int xx = u+X[i], yy = v+Y[i];
if (A[xx][yy] == k && F[xx][yy] == 0) DFS(xx,yy);
if (A[xx][yy] == k) F[u][v] = max(F[u][v],F[xx][yy]+1);
}
maxx = max(maxx,F[u][v]);
}
void Solve() {
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j) cin >> A[i][j];
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
if (F[i][j] == 0)
DFS(i,j);
cout << maxx;
exit(0);
}
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
freopen("CONSCELL.INP","r",stdin);
freopen("CONSCELL.OUT","w",stdout);
cin >> m >> n;
Solve();
return 0;
}
```
# **CONSCELL Truy Vết (YB2022)**
Lưu ý: Truy vết này in toạ độ các phần tử của dãy con tăng theo thứ tự tăng dần. **Không chắc chắn** đề thi sẽ ra truy vết theo như này.
**Đầu vào:**
3 3
3 2 1
4 5 8
19 6 7
**Đầu ra:**
8
1 3
1 2
1 1
2 1
2 2
3 2
3 3
2 3
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,m,d = 0,maxx = INT_MIN,A[10005][10005],F[10005][10005],C[100005],s,t,tmp;
bool kt = true;
int X[4] = {0,0,1,-1};
int Y[4] = {1,-1,0,0};
void DFS(int u, int v) {
F[u][v] = 1;
int k = A[u][v] + 1;
for (int i = 0; i < 4; ++i) {
int xx = u+X[i], yy = v+Y[i];
if (A[xx][yy] == k && F[xx][yy] == 0 && xx != 0 && xx != n+1 && yy != 0 && yy != m+1) DFS(xx,yy);
if (A[xx][yy] == k) F[u][v] = max(F[u][v],F[xx][yy]+1);
}
if (F[u][v] > maxx) {
maxx = F[u][v];
s = u;
t = v;
}
}
void Solve() {
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j) cin >> A[i][j];
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
if (F[i][j] == 0)
DFS(i,j);
cout << maxx << "\n";
while (kt) {
cout << s << " " << t << "\n";
kt = false;
tmp = A[s][t]+1;
for (int i = 0; i <= 3; ++i) {
int xx = s + X[i], yy = t + Y[i];
if (A[xx][yy] == tmp ) {
s = xx;
t = yy;
kt = true;
break;
}
}
}
}
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
freopen("CONSCELL.INP","r",stdin);
freopen("CONSCELL.OUT","w",stdout);
cin >> m >> n;
Solve();
return 0;
}
```
# **REWARD 0 Truy Vết (YB2022)**
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,A[100005],F[100005];
int main() {
freopen("REWARD.INP","r",stdin);
freopen("REWARD.OUT","w",stdout);
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> A[i];
F[1] = A[1];
F[2] = A[1]+A[2];
for (int i = 3; i <= n; ++i)
F[i] = max(F[i-1],max(F[i-2] + A[i], F[i-3]+A[i]+A[i-1]));
cout << F[n];
return 0;
}
```
# **REWARD Truy Vết (YB2022)**
Không chắc truy vết đúng hoàn toàn, có thể tự sinh test để kiểm chứng.
```cpp
#include <bits/stdc++.h>
using namespace std;
string tostr(int n) {
string kq = "";
while (n != 0) {
kq += char(n%10 + '0');
n/=10;
}
reverse(kq.begin(),kq.end());
return kq;
}
int n,A[100005],F[100005];
string Trace[100005];
int main() {
freopen("REWARD.INP","r",stdin);
freopen("REWARD.OUT","w",stdout);
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> A[i];
F[1] = A[1];
Trace[1] = tostr(A[1]);
F[2] = A[1]+A[2];
Trace[2] = tostr(A[1]) + " " + tostr(A[2]);
for (int i = 3; i <= n; ++i) {
F[i] = max(F[i-1],max(F[i-2] + A[i], F[i-3]+A[i]+A[i-1]));
if (F[i] == F[i-1]) Trace[i] = Trace[i-1];
else if (F[i] == F[i-2]+A[i]) Trace[i] = Trace[i-2] + " " + tostr(A[i]);
else Trace[i] = Trace[i-3] + " " + tostr(A[i-1]) + " " + tostr(A[i]);
}
cout << F[n] << "\n" << Trace[n];
return 0;
}
```
# **Rải Nhựa Đường (Đồ Thị)**
```cpp
#include <bits/stdc++.h>
using namespace std;
struct edge {
int u,v,w;
};
edge A[10005];
int n,a,Lab[100005],u,v,w,r1,r2,kq = 0,d = 0;
bool cmp(edge a, edge b) {
return a.w < b.w;
}
int getRoot(int v) {
while (Lab[v] > 0) v = Lab[v];
return v;
}
void Union(int r1, int r2) {
int x = Lab[r1] + Lab[r2];
if (Lab[r1] < Lab[r2]) {
Lab[r1] = x;
Lab[r2] = r1;
}
else {
Lab[r1] = r2;
Lab[r2] = x;
}
}
int main() {
freopen("<TENFILE>.INP","r",stdin);
freopen("<TENFILE>.OUT","w",stdout);
memset(Lab,-1,sizeof(Lab));
cin >> n >> a;
int m = 0;
while (cin >> u >> v >> w) {
m++;
A[m].u = u;
A[m].v = v;
A[m].w = w;
}
sort(A+1,A+n+1,cmp);
for (int i = 1; i <= n; ++i)
if (getRoot(A[i].u) != getRoot(A[i].v)) {
r1 = getRoot(A[i].u);
r2 = getRoot(A[i].v);
kq += A[i].w;
d++;
Union(r1,r2);
if (d == n-1) break;
}
cout << kq;
return 0;
}
```
# **Đặt Mìn (Đồ Thị)**
```cpp
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e4;
int n,m,A[1005][1005],u,v,w,Trace[1005][1005],maxx,x,y,minn = INT_MAX,s,t;
void Florentino() {
for (int u = 1; u <= n; ++u)
for (int v = 1; v <= n; ++v)
Trace[u][v] = v;
for (int k = 1; k <= n; ++k)
for (int u = 1; u <= n; ++u)
for (int v = 1; v <= n; v++)
if (A[u][v] > A[u][k] + A[k][v]) {
A[u][v] = A[u][k] + A[k][v];
Trace[u][v] = Trace[u][k];
}
}
int main() {
s = -1;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (j == i) A[i][j] = 0;
else A[i][j] = MAX;
for (int i = 1; i <= m; ++i) {
cin >> u >> v >> w;
A[u][v] = w;
A[v][u] = w;
}
Florentino();
for (int i = 1; i <= n; ++i) {
maxx = INT_MIN;
for (int j = 1; j <= n; ++j) {
if (maxx < A[i][j]) {
maxx = A[i][j];
x = i;
y = j;
}
}
if (maxx < minn) {
minn = maxx;
s = x;
t = y;
}
}
if (s == -1) {
cout << "NOT FOUND";
exit(0);
}
cout << s << "\n";
cout << t << " " << A[s][t] << "\n";
while (s != t) {
cout << s << " -> ";
s = Trace[s][t];
}
cout << t;
return 0;
}
```