## Spring Practices 06 心得&題解
[<<回主頁](https://hackmd.io/@r1cky/Sk2hKzga6)
### 前言
因為是學校練習用的,不知道題目能不能公開,但還是寫個心得好了。
今天在家 vir QQ
總共有五題,編號 A~E
### pA
找不比輸入 $n$ 大的最高的 $10^x$,那答案會是 $n-10^x$。
```cpp=
// Author : rickytsung
// Problem :
// Date :
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
#define i64 long long
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pii pair<int, int>
#define f first
#define s second
#define pb(x) push_back(x)
using namespace std;
mt19937 rng(114514);
const int mod1 = 998244353;
int rnd(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
i64 gcd(i64 a,i64 b){
if (a%b == 0) return(b);
else return(gcd(b, a%b));
}
i64 lcm(i64 a, i64 b){
return a/gcd(a, b) * b;
}
int main() {
IOS;
int n, t, p;
cin >> t;
while(t--){
cin >> n;
p = 1;
while(10*p <= n) p *= 10;
cout << n - p << '\n';
}
}
```
### pB
怪怪輸出題目。
``` cpp=
// Author : rickytsung
// Problem :
// Date :
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
#define i64 long long
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pii pair<int, int>
#define f first
#define s second
#define pb(x) push_back(x)
using namespace std;
mt19937 rng(114514);
const int mod1 = 998244353;
//i128 io template
inline void read(i128 &n){
i128 x = 0,f = 1;
char ch = getchar();
while(ch < '0'||ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while(ch>='0'&&ch<='9'){
x = (x<<1)+(x<<3)+(ch^48);
ch = getchar();
}
n = x * f;
}
inline void print(i128 n){
if(n<0){
putchar('-');
n*=-1;
}
if(n>9) print(n/10);
putchar(n % 10 + '0');
}
int rnd(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
i64 gcd(i64 a,i64 b){
if (a%b == 0) return(b);
else return(gcd(b, a%b));
}
i64 lcm(i64 a, i64 b){
return a/gcd(a, b) * b;
}
int main() {
IOS;
int n, t, p;
cin >> t;
while(t--){
cin >> n;
for(int i = 0; i < n; i++){
for(int j = 0; j < 2; j++){
for(int k = 0; k < n; k++){
if(!(i&1))cout << "##";
else cout << "..";
k++;
if(k >= n)break;
if(!(i&1)) cout << "..";
else cout << "##";
}
cout << '\n';
}
}
}
}
```
### pC
如果兩個點有一個維度的數值一樣,則它們中間有一個邊,數有幾個連通塊,答案會是連通塊-1。
```cpp=
// Author : rickytsung
// Problem :
// Date :
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
#define i64 long long
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pii pair<int, int>
#define f first
#define s second
#define pb(x) push_back(x)
using namespace std;
mt19937 rng(114514);
const int mod1 = 998244353;
int vis[1005];
vector<vector<int>> E(1005);
int rnd(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
i64 gcd(i64 a,i64 b){
if (a%b == 0) return(b);
else return(gcd(b, a%b));
}
i64 lcm(i64 a, i64 b){
return a/gcd(a, b) * b;
}
void walk(int now){
if(vis[now]) return;
vis[now] = 1;
for(auto &i:E[now]){
walk(i);
}
}
int main() {
IOS;
int n;
cin >> n;
int xy[n][2];
for(int i = 0; i < n; i++){
cin >> xy[i][0] >> xy[i][1];
}
for(int z = 0; z <= 1; z++){
for(int i = 0 ; i < n; i++){
for(int j = 0 ; j < n; j++){
if(xy[i][z] == xy[j][z]){
E[i].pb(j);
}
}
}
}
int ans = -1;
for(int i = 0; i < n; i++){
if(!vis[i]){
ans++;
walk(i);
}
}
cout << ans << '\n';
}
```
### pD
同 pC,用上禮拜 E 的方法壓邊的數量。
```cpp=
// Author : rickytsung
// Problem :
// Date :
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
#define i64 long long
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pii pair<int, int>
#define f first
#define s second
#define pb(x) push_back(x)
using namespace std;
mt19937 rng(114514);
const int mod1 = 998244353;
int vis[200005];
vector<vector<int>> E(200005);
int rnd(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
i64 gcd(i64 a,i64 b){
if (a%b == 0) return(b);
else return(gcd(b, a%b));
}
i64 lcm(i64 a, i64 b){
return a/gcd(a, b) * b;
}
void walk(int now){
if(vis[now]) return;
vis[now] = 1;
for(auto &i:E[now]){
walk(i);
}
}
int main() {
IOS;
int n;
cin >> n;
int xy[n][26];
memset(xy, 0, sizeof(xy));
string s;
for(int i = 0; i < n; i++){
cin >> s;
for(int j = 0 ; j < s.length(); j++){
xy[i][s[j] - 'a'] = 1;
}
}
for(int z = 0; z < 26; z++){
int pre = -1;
for(int i = 0 ; i < n; i++){
if(!xy[i][z]) continue;
if(pre != -1){
E[pre].pb(i);
E[i].pb(pre);
}
pre = i;
}
}
int ans = 0;
for(int i = 0; i < n; i++){
if(!vis[i]){
ans++;
walk(i);
}
}
cout << ans << '\n';
}
```
### pE
假設輸出有 n 個點,因為題目編號沒照順序,要離散化。
檢查 :
1. 是否連通
2. 是否是 n-1 個邊
3. 是否一個點的父節點不超過 1 個。
```cpp=
// Author : rickytsung
// Problem :
// Date :
#include <bits/stdc++.h>
#define i64 long long
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pii pair<int, int>
#define f first
#define s second
#define pb(x) push_back(x)
using namespace std;
mt19937 rng(114514);
const int mod1 = 998244353;
int rnd(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
i64 gcd(i64 a,i64 b){
if (a%b == 0) return(b);
else return(gcd(b, a%b));
}
i64 lcm(i64 a, i64 b){
return a/gcd(a, b) * b;
}
/*
6 8 5 3 5 2 6 4
5 6 0 0
8 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 0
3 8 6 8 6 4
5 3 5 6 5 2 0 0
-1 -1
*/
int cnt = 0;
void walk(vector<vector<int>> &T, bool* vis, int now){
if(vis[now]) return;
vis[now] = 1;
cnt++;
for(auto &i:T[now]){
walk(T, vis, i);
}
}
int main() {
//cin.ignore();
int t = 1, a, b, pa, pb;
while(1){
int ok = 1;
int edge = 0, vertex = 0;
set<int> fa;
map<int,int> has;
vector<vector<int>> T(200005);
bool vis[200005] = {0};
while(1){
cin >> a >> b;
if(a < 0){
return 0;
}
if(a == 0){
break;
}
edge++;
if(has.find(a) == has.end()){
has[a] = vertex++;
}
if(has.find(b) == has.end()){
has[b] = vertex++;
}
pa = has[a];
pb = has[b];
T[pa].pb(pb);
T[pb].pb(pa);
if(a == b) ok = 0;
if(fa.count(b)){
ok = 0;
}
fa.insert(b);
}
if(edge != vertex - 1){
ok = 0;
}
cout << "Case " << t++ << " ";
cnt = 0;
walk(T, vis , 0);
if(vertex == 0 || (fa.size() == vertex - 1 && ok && cnt == vertex)){
cout << "is a tree.\n";
}
else{
cout << "is not a tree.\n";
}
}
}
```