题目地址:
https://codeforces.com/contest/1243/problem/B2
题意:给两个互异的字符串 s 和 t ,选择某个 s[i] 和 t[j] 交换不超过 2n 次,问能否使得两个字符串相等。
题解:很显然有解的必要条件就是所有的字母出现都是偶数次,先判断这个。其次满足上面的必要条件之后必定有解,因为使用最多2次交换就可以消除至少1个位置上的不同。具体的做法是:固定已经相等的前半部分,然后假如 s[i]≠t[i],如果有某个后面的 s[id]=s[i] ,那么就把 s[id] 和 t[i] 交换。否则,必定存在某个后面的 t[id]=s[i] ,但是 t[id] 不能直接与 t[i] 交换,所以让它与 s[n] 交换(这样比较好写),然后把 s[n] 和 t[i] 交换。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 55;
int T, n;
char s[maxn], t[maxn];
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d %s %s", &n, s + 1, t + 1);
vector<pair<int, int> > V;
bool flag = 0;
for (int i = 1; i <= n; i++) {
if (s[i] != t[i]) {
bool tmp = 0;
for (int j = i + 1; j <= n; j++) {
if (t[i] == t[j]) {
V.push_back(make_pair(i, j));
swap(s[i], t[j]);
tmp = 1; break;
} else if (t[i] == s[j]) {
V.push_back(make_pair(j, j));
swap(s[j], t[j]);
V.push_back(make_pair(i, j));
swap(s[i], t[j]);
tmp = 1; break;
}
}
if (!tmp) { flag = 1; break; }
}
}
if (flag) { printf("No\n"); continue; }
printf("Yes\n%d\n", V.size());
vector<pair<int,int> >::iterator iter;
for(iter=V.begin();iter!=V.end();iter++){
cout<<(*iter).first<<" "<<(*iter).second<<endl;
}
}
return 0;
}
第二题:洛谷P1090 合并果子
这里我想说的是怎么用优先队列和vector的结合吧
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
int n;cin>>n;
int ans=0;
for(int i=1;i<=n;i++){
int x;
cin>>x;
q.push(x);
}
while(q.size()>=2){
int a=q.top();q.pop();
int b=q.top();q.pop();
ans+=a+b;
q.push(a+b);
}
cout<<ans<<endl;
}