https://codeforces.com/contest/1243
B2. Character Swap (Hard Version)
题意:给定两个字符串s,t,每次可以在两个字符串中各选一个位置,再字符串间交换,最终要使两个字符串相同。操作数不要求最少,但要小于2n。
贪心构造
挨个遍历过去,如果两个字符串当前位置i不同,则先在s串中找到和s[i]相同的j,交换s[j],t[i];若找不到,则在t中找和s[i]相同的j,先交换s[j],t[j],再交换s[j],t[i]。
在每个位置最多交换2次,总共不超过2n。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include<bits/stdc++.h> using namespace std; #define ll long long const int N = 2e5 + 10; const int INF = 0x3f3f3f3f; const ll mod = 1e9 + 7; const ll inf = 1e18; int T; int n; char s[N], t[N]; int a[N], c[N]; typedef pair<int, int>pii; vector<pii>vc; int main() { cin >> T; while (T--) { scanf("%d", &n); scanf("%s", s); scanf("%s", t); fill(c, c + 26, 0); for (int i = 0; i < n; i++)c[s[i] - 'a']++, c[t[i] - 'a']++; for (int i = 0; i < 26; i++)if (c[i] & 1) n = 0; if (!n)puts("No"); else { vc.clear(); for (int i = 0; i < n; i++) { if (s[i] == t[i])continue; bool flg = 0; for (int j = i + 1; j < n; j++)if (s[i] == s[j]) { vc.push_back(pii(j, i)); swap(t[i], s[j]); flg = 1; break; } if (!flg) { for (int j = i + 1; j < n; j++)if (s[i] == t[j]) { vc.push_back(pii(j, j)); swap(s[j], t[j]); vc.push_back(pii(j, i)); swap(s[j], t[i]); break; } } } puts("Yes"); printf("%d\n", (int)vc.size()); for (pii p : vc) { printf("%d %d\n", p.first+1, p.second+1); } } } return 0; }
|
C. Tile Painting
题意:给定n,要求构造出一个长度为n的数列,每个位置和与他间隔为n的因数的位置上的数必须相同,问最多有多少个不同的数。
画几个图直接猜结论,如果n只含有一个质因数,则答案就为这个质因数,否则就是1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include<bits/stdc++.h> using namespace std; #define ll long long const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; ll n; int vis[N]; vector<int>pr; void init(int n) { for (int i = 2; i <= n; i++) { if (vis[i])continue; pr.push_back(i); for (int j = i; j <= n; j += i)vis[j] = 1; } } vector<ll>ans; int main() { cin >> n; if (n == 1) { puts("1"); return 0; } init(1000000); int t = (int)pr.size(), cnt = 0; for (int i = 0; i < t&&pr[i] <= n; i++) { if (n%pr[i] == 0) { cnt++; ans.push_back(pr[i]); while (n%pr[i] == 0)n /= pr[i]; } } if (n != 1)cnt++, ans.push_back(n); if (cnt > 1)puts("1"); else printf("%lld\n", ans[0]); return 0; }
|