唉现在还是只能做比赛里的部分模拟题,,,涉及算法的还是搞不定wwww
I - A+B问题
思路: 模拟加法。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
//判断是否需要开ll!!!
//判断是否需要初始化!!!
const int mod=1e9+7;
const int N=1e6;
int k,s[N],A[N],B[N];
string a,b;
int main()
{
// freopen("test.in","r",stdin);
// freopen("output.in", "w", stdout);
cin>>k;
cin>>a>>b;
int tot1=0,tot2=0;
for(int i=a.length()-1;i>=0;i--)
A[++tot1]=a[i]-'0';
for(int i=b.length()-1;i>=0;i--)
B[++tot2]=b[i]-'0';
int ss=0;
int cnt=0;
for(int i=1;i<=max(tot1,tot2);i++)
{
s[++cnt]=(A[i]+B[i]+ss)%k;
ss=(A[i]+B[i]+ss)/k;
}
while(ss)
{
s[++cnt]=ss%k;
ss=ss/k;
}
for(int i=cnt;i>=1;i--)
cout<<s[i];
cout<<'\n';
return 0;
}
F - +-串
思路: 要保证结果的绝对值最小,应保证+,-号差值尽可能小,所以对于每一次k的使用分类讨论即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
//判断是否需要开ll!!!
//判断是否需要初始化!!!
const int mod=1e9+7;
int t,k,a[3];
string s;
int main()
{
// freopen("test.in","r",stdin);
// freopen("output.in", "w", stdout);
cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
cin>>s;
cin>>k;
int len=s.length();
for(int i=0;i<len;i++)
{
if(s[i]=='+') a[1]++;
else a[2]++;
}
while(k)
{
if(a[1]>a[2])
{
a[2]++,a[1]--;
k--;
}
else if(a[2]>a[1])
{
a[2]--,a[1]++;
k--;
}
else if(a[1]==a[2])
{
a[1]--,a[2]++;
k--;
}
}
cout<<abs(a[1]-a[2])<<'\n';
}
return 0;
}
E - 骑士
思路: 结构体存每位骑士攻击力,防御力,生命值,及防御力和生命值的和,按照攻击力排序,遍历求每位骑士需要的生命药剂之和即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
//判断是否需要开ll!!!
//判断是否需要初始化!!!
const int mod=1e9+7;
const int N=2e5+5;
int t,n;
struct node
{
int a,b,h;
int hurt;
}e[N];
bool cmp(node a,node b)
{
if(a.a>b.a) return true;
else return false;
}
int main()
{
// freopen("test.in","r",stdin);
// freopen("output.in", "w", stdout);
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
e[i].a=0,e[i].b=0;
e[i].h=0,e[i].hurt=0;
}
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].h);
e[i].hurt=e[i].b+e[i].h;
}
sort(e+1,e+1+n,cmp);
ll ans=0;
for(int i=1;i<=n;i++)
{
if(i==1&&e[i+1].a>=e[i].hurt)
{
ans+=(e[i+1].a-e[i].hurt+1);
}
else if(i!=1)
{
if(e[1].a>=e[i].hurt)
ans+=(e[1].a-e[i].hurt+1);
}
}
printf("%lld\n",ans);
}
return 0;
}
os:一直卡TLE,改了输入输出,改了初始化方法才好的,,,罚时+++
D - 删除子序列
思路: 遍历T,给每一位编号;遍历S,统计最多可以删去T的数量。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
//判断是否需要开ll!!!
//判断是否需要初始化!!!
const int mod=1e9+7;
const int N=28;
int st,n,m;
string s,t;
struct node
{
int num;
char c;
} e[N];
int main()
{
// freopen("test.in","r",stdin);
// freopen("output.in", "w", stdout);
scanf("%d",&st);
while(st--)
{
memset(e,0,sizeof(e));
scanf("%d%d",&n,&m);
cin>>s>>t;
for(int i=0;i<m;i++)
{
e[i].c=t[i];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(j==0&&s[i]==e[j].c) e[j].num++;
else if(j!=0&&s[i]==e[j].c&&e[j-1].num>e[j].num) e[j].num++;
} //要保证删除T,顺序一定,计数加个条件即可满足题意
}
printf("%d\n",e[m-1].num);
}
return 0;
}
os:因为没有初始化WA了n发,太菜了,不过感觉这样比标解好做
B - 价值序列
思路: 标解:
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
//判断是否需要开ll!!!
//判断是否需要初始化!!!
const int mod=998244353;
const int N=1e5+5;
int t,n;
ll a[N];
ll pmod(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
int main()
{
// freopen("test.in","r",stdin);
// freopen("output.in", "w", stdout);
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ll ans=1;
for(int i=1;i<=n;i++)
{
int j=i;
while(j<n&&a[j+1]==a[i]) j++;
if(i-1>=1&&j+1<=n&&(a[i-1]<a[i]&&a[j+1]>a[i]||a[i-1]>a[i]&&a[j+1]<a[i]))
ans=ans*pmod(2,j-i+1)%mod;
else ans=ans*(pmod(2,j-i+1)+mod-1)%mod;
i=j;
}
printf("%lld\n",ans);
}
return 0;
}
os:还是思维题,还需要锻炼
J - 牛妹的数学难题
思路: a[i]=0时,相乘结果为0,就可以用组合数判断k个数相乘有几个1,几个2,求所有非0情况的和即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
//判断是否需要开ll!!!
//判断是否需要初始化!!!
const int mod=998244353;
const int N=1e7+5;
ll n,k;
ll func[N],a[N],b[4],inv[N],p2[N];
ll C(ll n,ll m)
{
if(n<m) return 0;//注意特判!
return func[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
// freopen("test.in","r",stdin);
// freopen("output.in", "w", stdout);
func[0]=func[1]=inv[0]=inv[1]=1;
for(int i=2;i<=N-5;i++)
{
func[i]=func[i-1]*i%mod;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
for(int i=2;i<=N-5;i++)
inv[i]=inv[i-1]*inv[i]%mod;
p2[0]=1;
for(int i=1;i<=N-5;i++)
p2[i]=p2[i-1]*2%mod;
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[a[i]]++;
}
ll ans=0;
for(int i=0;i<=k;i++)
{
ans=(ans+C(b[2],i)*p2[i]%mod*C(b[1],k-i)%mod)%mod;
}
printf("%lld\n",ans);
return 0;
}
os:注意求组合数的方法!除了使用费马小定理快速幂求,也可以这样预处理求。
若有错误请指教orzorz