Tokitsukaze and Balance String (hard)
题目链接
题目描述🥰
题目思路😀
这道题一开始我想的是找规律进行模拟,找了一个规律但是只能过一些数据😅
正确解法应该是分类进行讨论,但是在分类讨论之前我们需要知道一些结论,我们通过观察可以发现平衡串的两个结论
- 首尾相同的字符串一定是平衡的
- 首尾不相同的字符串一定是不平衡的。
所以我们可以对首尾元素进行讨论,在讨论之前,我们需要统计字符串里面的'?'个数,记为cnt
- 如果首尾元素都不是'?'
- 如果首尾元素不相等,那么就只有首元素反转或者尾元素反转才能平衡,而总共有2^cnt个串,所以答案是2^(cnt+1)
- 如果首尾元素相等,那么只有首元素反转或者尾元素反转才不能平衡,总共有2^cnt个串,所以答案是2^(cnt)*(n-2)
- 如果首尾元素里面有一个'?'
- 如果将首尾中的 '?' 填成首尾相同,那么字符串中间任意翻转一个都行,这样的贡献是2^(cnt-1)*(n-2)。
- 如果将首尾中的 '?' 填成首尾不同,那么字符串首尾任意翻转一个都行, 这样的贡献是2^(cnt-1)*2。
- 如果首尾元素都是'?'
- 如果将首尾中的 '?' 填成首尾相同,那么字符串中间任意翻转一个都行,这样的贡献就是2^(cnt-2)*(n-2)*2(因为两个?可以变成11或是00,所以要乘2)
- 如果将首尾中的 '?' 填成首尾不同,那么字符串首尾任意翻转一个都行, 这样的贡献是2^(cnt-2)*4(因为首尾的??可以是10->01,也可以是11->10,也可以是00->10,也可以是01->10,所以*4)
提醒:我们需要对于n==1的情况进行特判
- 如果这个是'?'的话,就输出2
- 如果是数字,就输出1
对于数据较大的幂次运算,应该使用快速幂,否则TLE警告🤡
AC代码🧠
// Problem: Tokitsukaze and Balance String (hard)
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/95336/C
// Memory Limit: 512 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define dev1(a) cout << #a << '=' << a << endl;
#define dev2(a, b) cout << #a << " = " << a << " " << #b << " = " << b << endl;
#define dev3(a, b, c) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << endl;
#define dev4(a, b, c, d) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << " " << #d << " = " << d << endl;
#define dev5(a, b, c, d, e) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << " " << #d << " = " << d << " " << #e << " = " << e << endl;
#define vec(a) \
for (int i = 0; i < a.size(); i++) \
cout << a[i] << ' '; \
cout << endl;
#define darr(a, _i, _n) \
cout << #a << ':'; \
for (int ij = _i; ij <= _n; ij++) \
cout << a[ij] << ' '; \
cout << endl;
#define cin(a,n) \
for(int i=0;i<n;i++) \
cin>>a[i];
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
int res=1;
if(a==0)return 0;
while(k)
{
if(k&1)res=(int)res*a;
k>>=1;
a=(int)a*a;
}
return res;
}
#define fi first
#define se second
#define caseT \
int T; \
cin >> T; \
while (T--)
#define int long long
// #define int __int128
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
// const int N = ;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b)
{
return a * b / gcd(a, b);
}
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int pow_mod(int a, int n, int m)
{
int ans = 1;
while(n){
if(n&1){
ans = (ans * a) % m;
}
a = (a * a) % m;
n >>= 1;
}
return ans;
}
void solve()
{
int n;
cin>>n;
string s;
cin>>s;
int cnt=0;
for(auto x:s)if(x=='?')cnt++;
if(s.size()==1)
{
if(s[0]=='?')cout<<2<<endl;
else cout<<1<<endl;
return;
}
if(s[0]!='?'&&s[n-1]!='?')
{
if(s[0]!=s[n-1])cout<<pow_mod(2,cnt+1,MOD)<<endl;
else cout<<pow_mod(2,cnt,MOD)*(n-2)%MOD<<endl;
}else{
cout<<pow_mod(2,cnt-1,MOD)*n%MOD<<endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
caseT
solve();
return 0;
}
/*
*/
Tokitsukaze and Concatenate Palindrome
题目链接
题目描述🥰
题目思路😀
首先题目提及的可以不考虑字符串a和字符串b的排列顺序,所以我们只需要考虑字符串a和字符串b里面字符的出现次数,和开心消消乐一样的思维,用一个a里面的字符消一个b里面的字符。为了后续的讲解方便,我就把短的一个串叫做a串,长的一个串叫做b串。
解题步骤:
- 首先两个串进行互消,如果一个字符ch在a和b里面都有,就在a和b里面各自消去一个字符ch
- 其次我们可以统计a字符串里面的没有被消掉的字符个数,记作sum,因为最后要形成的是回文串,所以短的那个串里面的字符不能相互抵消,只能替换。
- 我们再对b字符串里面没有被消掉的字符个数进行处理,因为长的字符串内可以进行互消,所以我们统计没有被消去的字符里面出现次数为奇数的字符即可,记作ans。
- 对sum 和ans的大小进行判断
- 如果sum>=ans,就说明只能替换的字符更多,所以答案为cnt(cnt个字符都可以直接替换成和ans个字符一样的字符)
- 如果sum<ans,那么就先将s 与 抵消,再让 两两抵消,答案就是sum+floor((ans-sum)/2)
时间复杂度O(n)
AC代码🧠
// Problem: Tokitsukaze and Concatenate Palindrome
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/95336/D
// Memory Limit: 512 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define dev1(a) cout << #a << '=' << a << endl;
#define dev2(a, b) cout << #a << " = " << a << " " << #b << " = " << b << endl;
#define dev3(a, b, c) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << endl;
#define dev4(a, b, c, d) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << " " << #d << " = " << d << endl;
#define dev5(a, b, c, d, e) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << " " << #d << " = " << d << " " << #e << " = " << e << endl;
#define vec(a) \
for (int i = 0; i < a.size(); i++) \
cout << a[i] << ' '; \
cout << endl;
#define darr(a, _i, _n) \
cout << #a << ':'; \
for (int ij = _i; ij <= _n; ij++) \
cout << a[ij] << ' '; \
cout << endl;
#define cin(a,n) \
for(int i=0;i<n;i++) \
cin>>a[i];
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
int res=1;
if(a==0)return 0;
while(k)
{
if(k&1)res=(int)res*a;
k>>=1;
a=(int)a*a;
}
return res;
}
#define fi first
#define se second
#define caseT \
int T; \
cin >> T; \
while (T--)
// #define int long long
// #define int __int128
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 99999999;
// const int N = ;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b)
{
return a * b / gcd(a, b);
}
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
void solve()
{
int n,m;
cin>>n>>m;
string a,b;
cin>>a>>b;
if(n>=m)
{
swap(n,m);
swap(a,b);
}
map<int,int>hash,mp;
for(auto x:a)hash[x]++;
for(auto x:b)mp[x]++;
for(auto x:b){
if(hash[x])
{
hash[x]--;
mp[x]--;
}
}
int sum=0;//记录的短的那个字符串里面不能被消去的字符个数
for(auto x:hash)sum+=x.second;
int ans=0;//记录的长的那个字符串里面不能被消去的字符字符
for(auto x:mp)if(x.second&1)ans++;
//短串里面的字符不能进行抵消,只能进行替换
if(sum>=ans)cout<<sum<<endl;
else cout<<sum+floor((ans-sum)/2)<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
caseT
solve();
return 0;
}
/*
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】