2023杭电第八场补题报告1005 1007 1010
1005 0 vs 1 (hdu.edu.cn)
思路
直接考虑左右两端,当两端都可以选择且内层不连续时,还需要再往内侧考虑两层,分类讨论双指针模拟即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve();
signed main() {
// cin.sync_with_stdio(0);
// cin.tie(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
/*
01 00 00 10 0必胜
01 00 01 10 0必胜
01 00 10 10 0必胜
01 00 11 10 0必胜
01 01 01 10 拿左边
01 01 10 10 随便拿
01 01 11 10 只能拿左
01 10 01 10 1必胜
01 11 11 10 1必胜
01 10 11 10 1必胜
*/
map<string, int> mp = {{"01000010", 1}, // 1赢,-1输,-2拿左
{"01000110", 1}, {"01001010", 1}, {"01001110", 1},
{"01010110", 3}, {"01011010", -2}, {"01011110", -2},
{"01100110", -1}, {"01111110", -1}, {"01101110", -1}};
void flip(string& s) {
for (int i = 0; i < s.size(); i++) {
if (s[i] == '0')
s[i] = '1';
else
s[i] = '0';
}
}
void solve() {
int n;
cin >> n;
string s;
cin >> s;
int l = 0, r = n - 1;
int ed = 0;
while (l <= r) {
if (s[l] != s[r]) {
if (s[l] == ed + '0')
l++;
else
r--;
} else {
if (s[l] != ed + '0') {
cout << 1 - ed << "\n";
return;
} else {
int len = r - l + 1;
if (len == 1) {
cout << -1 << "\n";
return;
}
if (len == 2) {
cout << ed << "\n";
return;
}
if (len == 3) {
if (s[l + 1] == ed + '0') {
cout << ed << "\n";
return;
} else {
cout << -1 << "\n";
return;
}
}
if (len >= 4) {
if (s[l + 1] == ed + '0' || s[r - 1] == ed + '0') {
cout << ed << "\n";
return;
} else {
if (len == 4) {
cout << "-1\n";
return;
} else if (len == 5) {
if (s[l + 2] == ed + '0') {
cout << "-1\n";
return;
} else {
cout << 1 - ed << "\n";
return;
}
} else if (len == 6) {
if (s[l + 2] == s[r - 2]) {
cout << s[l + 2] << "\n";
return;
} else {
cout << "-1\n";
return;
}
} else if (len == 7) {
if (s[l + 2] == s[l + 3] || s[r - 2] == s[r - 3]) {
cout << s[l + 3] << '\n';
return;
} else {
if (s[l + 3] == ed + '0') {
cout << 1 - ed << "\n";
return;
} else {
cout << "-1\n";
return;
}
}
} else {
string tmp = "";
for (int i = l + 2; i < l + 4; i++) {
tmp += s[i];
}
for (int i = r - 3; i < r - 1; i++) {
tmp += s[i];
}
if (s[l] == '1') flip(tmp);
if (mp.count(tmp)) {
int x = mp[tmp];
if (x == 1) {
cout << ed << "\n";
return;
} else if (x == -1) {
cout << 1 - ed << "\n";
return;
} else if (x == -2) {
l++;
} else
r--;
} else {
reverse(tmp.begin(), tmp.end());
int x = mp[tmp];
if (x == 1) {
cout << ed << "\n";
return;
} else if (x == -1) {
cout << 1 - ed << "\n";
return;
} else if (x == -2) {
r--;
} else {
l++;
}
}
}
}
}
}
}
ed = 1 - ed;
}
cout << "-1\n";
}
1007 Solubility (hdu.edu.cn)
思路
并查集裸题。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n, m;
int a[N];
vector<int> p;
int find(int i) {
if (p[i] == i)
return i;
else
return p[i] = find(p[i]);
}
void solve() {
cin >> n >> m;
p.resize(n + 10);
for (int i = 1; i <= n; i++) {
p[i] = i;
}
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
if (u < v) swap(u, v);
p[find(u)] = find(p[v]);
// cout << p[u] << ' ' << p[v] << "\n";
}
// for (int i = 1; i <= n; i++) {
// p[i] = find(p[i]);
// }
int k;
cin >> k;
set<int> st;
for (int i = 1; i <= k; i++) {
int x;
cin >> x;
st.insert(find(p[x]));
}
if (st.size() == 1)
cout << "YES\n";
else
cout << "NO\n";
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}
1010 Rikka with Square Numbers (hdu.edu.cn)
思路
考虑平方差公式,如果不能由一步变过来,那么就考虑差值。最多三步。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n;
int a[N];
map<int, int> mp;
void solve() {
int x, y;
cin >> x >> y;
int d = abs(x - y);
if (mp.count(d)) {
cout << 1 << "\n";
return;
}
if (d % 2 == 1)
cout << 2 << "\n";
else {
for (int i = 2; i * i <= d; i++) {
int p = d / i;
if (d % i == 0) {
if ((p + i) % 2 == 0) {
cout << 2 << "\n";
return;
}
}
}
for (int i = 1; i * i <= d; i++) {
if (mp.count(d - i * i)) {
cout << 2 << "\n";
return;
}
}
cout << 3 << "\n";
return;
}
}
signed main() {
IOS;
int t = 1;
for (int i = 1; i <= 100000; i++) mp[i * i] = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}