(求求佬了~~,看在我连夜写题解的份上,可以麻烦佬点一个小赞嘛~~)
A - Verify Password
1.首先检查是否存在字母后面有数字的情况
2.依次检查s[i]与s[i+1]不构成严格小于关系即可
3.可以使用isxxxx函数更方便的判断是否为字母或数字(非必要)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <set>
#include <map>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <list>
#include <string>
#include <cmath>
#include <bitset>
#include <stack>
#include <math.h>
#include <functional>
#define int long long
#define endl '\n'
#define ull unsigned long long
#define ll long long
#define pii pair<int,int>
#define cy cout<<"Yes"<<'\n'
#define cn cout<<"No"<<'\n'
#define forn(i,begin,end,add) for(ll (i)=(begin);(i)<=(end);(i)+=(add)) //begin是i的起始,end是i的终止,add是每次加的大小
#define rforn(i,begin,end,sub) for(ll (i)=(end);(i)>=(begin);(i)-=(sub)) //r是倒序遍历
#define vv vector
#define inf32 INT32_MAX/2
#define inf64 INT64_MAX/2
#define LD long double
#define PI acos(-1)
#define debug(a,b) cout<<a<<b
#define eps 1e-12
const int N = 4e5 + 100;
ll T;
const ll mod = 998244353;
void solve() {
int n; cin >> n;
string s; cin >> s;
if (n == 1)
{
cy;
return;
}
forn(i, 0, s.size() - 2, 1) {
if (isalpha(s[i]) && !isalpha(s[i + 1])) {
cn;
return;
}
}
int flagn = 1;
int flaga = 1;
forn(i, 0, n-1-1, 1) {
if (isdigit(s[i]) && isdigit(s[i + 1])) {
if (s[i] > s[i+1])
flagn = 0;
}
if (isalpha(s[i]) && isalpha(s[i + 1]))
if (s[i] > s[i+1])
flaga = 0;
}
if (flagn&&flaga)
cy;
else
cn;
}
signed main() {
T = 1;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--)
solve();
return 0;
}
B - Increase/Decrease/Copy
注:最大值记为mx_i=max(a[i],b[i]),最小值记为mn_i=min(a[i],b[i]),b[n+1]记为now,答案记为ans
根据题目观察而得:
1.如果mn_i<=now<=mx_i,那么可以在将a[i]变成b[i]的过程中将now复制出来,而不需要额外的花费。
2.否则,要不通过mx_i,要不通过mn_i将now拷贝出来。
3.最后注意噢,不要忘记复制也算一次操作,需要ans++
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <set>
#include <map>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <list>
#include <string>
#include <cmath>
#include <bitset>
#include <stack>
#include <math.h>
#include <functional>
#define int long long
#define endl '\n'
#define ull unsigned long long
#define ll long long
#define pii pair<int,int>
#define cy cout<<"Yes"<<'\n'
#define cn cout<<"No"<<'\n'
#define forn(i,begin,end,add) for(ll (i)=(begin);(i)<=(end);(i)+=(add)) //begin是i的起始,end是i的终止,add是每次加的大小
#define rforn(i,begin,end,sub) for(ll (i)=(end);(i)>=(begin);(i)-=(sub)) //r是倒序遍历
#define vv vector
#define inf32 INT32_MAX/2
#define inf64 INT64_MAX/2
#define LD long double
#define PI acos(-1)
#define debug(a,b) cout<<a<<b
#define eps 1e-12
const int N = 4e5 + 100;
ll T;
const ll mod = 998244353;
void solve() {
int n; cin >> n;
vv<int>a(n + 1);
vv<int>b(n + 2);
forn(i, 1, n, 1)
cin >> a[i];
forn(i, 1, n+1, 1)
cin >> b[i];
int now = b[n + 1];
int ans = 0;
int flag = 0;
int s = inf32;
forn(i, 1, n, 1){
ans += abs(a[i] - b[i]);
int mn, mx;
if (now >= (mn = min(a[i], b[i])) && now <= (mx = max(a[i], b[i])))
flag = 1;
else {
int sub = min(abs(now - mn), abs(now - mx));
s = min(s, sub);
}
}
ans++;
if (flag)
cout << ans << endl;
else
cout << ans + s << endl;
}
signed main() {
T = 1;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--)
solve();
return 0;
}
C - Job Interview
注:选择ai的值记为1,选择bi的值记为2
通过观察题目可以发现以下性质:
1.一个员工不到来只会影响后面的员工选择,所以可以从后往前依次考虑
2.对于一个员工,如果他相当1,但是被选择了2,那么他后面的所有人都是2
3.所以可以依次从后向前遍历,如果该员工不来,则让出他所选择的位置,给后面第一个想要这个位置的人(记为want1/want2)
4.而由于第2条,则want1接受1后,会将他的2传递给最后一个人(最后一个人太可怜了呜呜~~~,只能接受别人不要的)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <set>
#include <map>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <list>
#include <string>
#include <cmath>
#include <bitset>
#include <stack>
#include <math.h>
#include <functional>
#define int long long
#define endl '\n'
#define ull unsigned long long
#define ll long long
#define pii pair<int,int>
#define cy cout<<"Yes"<<'\n'
#define cn cout<<"No"<<'\n'
#define forn(i,begin,end,add) for(ll (i)=(begin);(i)<=(end);(i)+=(add)) //begin是i的起始,end是i的终止,add是每次加的大小
#define rforn(i,begin,end,sub) for(ll (i)=(end);(i)>=(begin);(i)-=(sub)) //r是倒序遍历
#define vv vector
#define inf32 INT32_MAX/2
#define inf64 INT64_MAX/2
#define LD long double
#define PI acos(-1)
#define debug(a,b) cout<<a<<b
#define eps 1e-12
const int N = 4e5 + 100;
ll T;
const ll mod = 998244353;
void solve() {
int n, m; cin >> n >> m;
vv<pii>nums(n + m + 1 + 1);
forn(i, 1, n + m + 1, 1) {
cin >> nums[i].first;
}
forn(i, 1, n + m + 1, 1) {
cin >> nums[i].second;
}
vv<int>choos(n + 1);
int ans = 0;
int cntn = 0;
int cntm = 0;
vv<int>rs(n + m + 1 + 1);//答案
vv<int>choose(n + m + 1 + 1);//这个人最终当了那个
vv<int>need(n + m + 1+1);//这个人想要当那个
//记录这个人想要当那个
forn(i, 1, n+m+1, 1) {
if (nums[i].first > nums[i].second)
need[i] = 1;
else
need[i] = 2;
}
//跑前n+m个人,并且记录这个人最终当了那个
forn(i, 1, n + m, 1) {
if (nums[i].first > nums[i].second)
{
if (cntn == n)
cntm++, ans += nums[i].second, choose[i] = 2;
else
cntn++, ans += nums[i].first, choose[i] = 1;
}
else {
if (cntm == m)
cntn++, ans += nums[i].first, choose[i] = 1;
else
cntm++, ans += nums[i].second, choose[i] = 2;
}
}
rs[n + m + 1] = ans;//只考虑前n+m个人的最终值
int wt1 = n + m + 1;//想要1的元素下标
int wt2 = n + m + 1;//想要2的元素下标
//因为到了want1的元素后已经没有了1,所以后面的元素必定全选2,也就是,want1的会把它的2留给最后一个人
//want2的同理
rforn(i, 1, n + m , 1) {
if (choose[i] == 1) {//腾出一个1给后面
rs[i] = ans + nums[wt1].first //加上第wt个人现在可以选的
- nums[i].first //减去第i个人原本选的
- nums[wt1].second //减去第wt个人的原本选的
+ nums[n + m + 1].second;//加上最后一个人被迫接受的
}
else {//腾出一个2给后面
rs[i] = ans + nums[wt2].second
- nums[i].second
- nums[wt2].first
+ nums[n + m + 1].first;
}
//实时更新want值
if (need[i] != choose[i]) {
if (need[i] == 1)
wt1 = i;
if (need[i] == 2)
wt2 = i;
}
}
forn(i, 1, n + m + 1, 1)
cout << rs[i] << ' ';
cout << endl;
cout << endl;
}
signed main() {
T = 1;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--)
solve();
return 0;
}