1.签到模拟:https://ac.nowcoder.com/acm/contest/82401/A
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int t;
bool check(int x)
{
if(x%7==0) return 1;
while(x)
{
int w=x%10;
if(w==7) return 1;
x/=10;
}
return 0;
}
int main()
{
cin>>t;
while(t--)
{
int n,a,k;
cin>>n>>a>>k;
for(int i=0;i<=k-1;i++)
{
int w=a+1+n*i;
if(check(w)) cout<<"p"<<" ";
else cout<<w<<" ";
}
cout<<endl;
}
}
2.思维题:https://ac.nowcoder.com/acm/contest/82401/B
注意到有一个性质那就是a+b==c,c显然是定制,于是我们就让|a-b|尽可能大即可。
同时在字符串转化数字时边转边取模即可。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
string a,b;
int mod=998244353;
int main()
{
cin>>n>>a>>b;
for(int i=0;i<n;i++)
{
if(a[i]>b[i]) swap(a[i],b[i]);
}
long long ans1=0,ans2=0;
for(int i=0;i<=n-1;i++)
{
ans1=(10*ans1+a[i]-'0')%mod;
ans2=(10*ans2+b[i]-'0')%mod;
}
cout<<ans1*ans2%mod;
}
3.逆元+数学:https://ac.nowcoder.com/acm/contest/82401/C
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
typedef long long ll;
ll qpow(ll a, ll k) // 求a^k mod p
{
ll res =1;
while (k)
{
if (k & 1) res = res * a % mod;
a = a * a % mod;
k >>= 1;
}
return res;
}
int main()
{
int T;
cin>>T;
while(T--)
{
ll m,a,b,c;
cin>>m>>a>>b>>c;
ll d=m*m%mod*m%mod;
ll l1=m;
ll l3=m*(m-1)%mod*(m-2)%mod;
ll l2=((d-l1-l3)%mod+mod)%mod;
ll res=l1*c%mod+l2*b%mod+l3*a%mod;
res=res%mod;
res=res*qpow(d,mod-2)%mod;
cout<<(res+mod)%mod<<endl;
}
}
4.打表题(规律题):https://ac.nowcoder.com/acm/contest/82401/D
先按照题意DFS模拟一下发现就是n位的二进制中,把原下标的1的位置对称一下即可,下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
cin>>n>>m;
while(m--)
{
long long x;
cin>>x;
long long res=0;
for(int i=n-1;i>=0;i--)
{
res+=((x>>i)&1)<<(n-1-i);//对称
}
cout<<res<<endl;
}
}
5.巧妙地前缀和/DP:https://ac.nowcoder.com/acm/contest/82401/E
我们先求一下sum[i]表示考虑1--i的答案,sum[i]=sum[i-1]+此处的贡献
此处的贡献就是(1--i-1)中0/1的个数*i-0/1的位置和,那么对于[i,r]就是两个相减吗?
注意我们还要减去i前面的0以及区间内的1的贡献,以及i前面的1以及区间内的0的贡献,我们把式子化简一下可以用前面有多少个0/1以及0/1下标的前缀和快速维护出来。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,mod=998244353;
string ck;
ll c[200010],c0[200010],c1[200010];
ll s0[200010],s1[200010];
ll sum[200020];//sum[i]表示考虑1--i的答案
int main()
{
cin>>n>>m;
cin>>ck;
for(int i=1;i<=n;i++) c[i]=ck[i-1]-'0';
for(int i=1;i<=n;i++)
{
c0[i]=c0[i-1]+(c[i]==0);
c1[i]=c1[i-1]+(c[i]==1);
s0[i]=s0[i-1];
s1[i]=s1[i-1];
if(c[i]==0) s0[i]=(s0[i]+i)%mod;
else s1[i]=(s1[i]+i)%mod;
}
for(int i=1;i<=n;i++)
{
sum[i]=sum[i-1];
if(c[i]==0) sum[i]=(sum[i]+i*c1[i]-s1[i])%mod;
else sum[i]=(sum[i]+i*c0[i]-s0[i])%mod;
}
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
ll ans=sum[r]-sum[l-1];
ans-=(c0[l-1]*(s1[r]-s1[l-1])-(c1[r]-c1[l-1])*s0[l-1])%mod;
ans=(ans+2*mod)%mod;
ans-=(c1[l-1]*(s0[r]-s0[l-1])-(c0[r]-c0[l-1])*s1[l-1])%mod;
ans=(ans+2*mod)%mod;
cout<<ans<<endl;
}
}