B 括号序列
思路:用栈去模拟,左括号进栈右括号出栈(对应括号),最后判断一下是否栈空,空说明没问题,否则不行。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;cin>>s;
stack<char>st;
bool flag=true;
for(int i=0;i<s.size();i++){
if(s[i]=='['||s[i]=='{'||s[i]=='(')st.push(s[i]);
if(s[i]==']'){
if(st.top()!='['){
flag=false;
break;
}else{
st.pop();
}
}
if(s[i]==')'){
if(st.top()!='('){
flag=false;
break;
}else{
st.pop();
}
}
if(s[i]=='}'){
if(st.top()!='{'){
flag=false;break;
}else{
st.pop();
}
}
}
if(flag&&st.empty()){
cout<<"Yes"<<endl;
}else cout<<"No"<<endl;
}
A 欧几里得
思路:
通过手动枚举:
得到递推式子,就很好写代码了。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
int p[100];
p[0]=1;p[1]=3;p[2]=5;
for(int i=3;i<=n;i++)p[i]=p[i-1]+p[i-2];
cout<<p[n]<<endl;
}
}
C 子段乘积
思路:
类似最长连续字段和的思路,定义dp[i]:表示前i个数最大连续乘积 。
状态转移方程:dp[i]=(a[i]*dp[i-1])。
不过这题还需要求一下逆元,因为(a/b)%p = (a%p * inv(b)%p)%p。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int maxn = 1e7 + 10;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
ll a[maxn],dp[maxn],len[maxn];
/* dp[i]:表示前i个数最大连续乘积 */
ll exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得算法
{
if(b==0)
{
x=1,y=0;
return a;
}
ll ret=exgcd(b,a%b,y,x);
y-=a/b*x;
return ret;
}
ll getInv(ll a,ll mod)//求a在mod下的逆元,不存在逆元返回-1
{
ll x,y;
ll d=exgcd(a,mod,x,y);
return d==1?(x%mod+mod)%mod:-1;
}
int main(){
ll n,k;
cin>>n>>k;
dp[0]=1;
for(ll i=1;i<=n;i++)cin>>a[i];
for(ll i=1;i<=n;i++){
if(a[i]==0){
len[i]=0;
dp[i]=1;
}else{
dp[i]=a[i]*dp[i-1]%mod;
len[i]=len[i-1]+1;
}
}
ll ans=0;
for(ll i=1;i<=n;i++){
if(len[i]>=k){
ans=max(ans,(dp[i]%mod*getInv(dp[i-k],mod)%mod)%mod);
}
}
cout<<ans<<endl;
}
E 最小表达式
思路:思路很简单,贪心数字越小的越往权位高的地方放,然后平均放一下就行了,不过这个卡了一个高精度加法。
代码:
#include<iostream>
#include<sstream>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll ;
const int maxn = 1e7+10;
char str[maxn];
map<ll,string>mp;
string add1(string s1,string s2)
{
if(s1==""&&s2=="")return "0";
else if(s1=="")return s2;
else if(s2=="")return s1;
string maxs=s1,mins=s2;
if(s1.length()<s2.length()){
maxs=s2;
mins=s1;
}
int a=maxs.length()-1,b=mins.length()-1;
for(int i=b;i>=0;i--)
maxs[a--]+=mins[i]-'0';
for(int i=maxs.length()-1;i>0;i--)
if(maxs[i]>'9')
{
maxs[i]-=10;
maxs[i-1]++;
}
if(maxs[0]>'9')
{
maxs[0]-=10;
maxs='1'+maxs;
}
return maxs;
}
int main(){
string s;cin>>s;
ll count=0;
ll cnt=0;
for(ll i=0;i<s.size();i++){
if(s[i]=='+')count++;//统计字符+
else str[cnt++]=s[i];//保存不带字符+的原数组
}
count++;
sort(str,str+cnt);
ll start=0;
for(ll i=0;i<cnt;i++){
mp[start++%count]+=str[i];
}
map<ll,string>::iterator it;
string ans = "0";
for(it=mp.begin();it!=mp.end();it++){
ans=add1(ans,it->second);
}
cout<<ans<<endl;
}