比赛链接:
https://ac.nowcoder.com/acm/contest/549#question
A | 小A的签到题 |
打表找规律,如果是偶数输出-1,如果是偶数输出1.
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct mat
{
ll m[5][5];
};
mat a,b,c;
mat mul(mat a,mat b)
{
memset (c.m,0,sizeof(c.m));
for (int i=0;i<2;i++)
{
for (int j=0;j<2;j++)
{
for (int k=0;k<2;k++)
{
c.m[i][j]+=a.m[i][k]*b.m[k][j];
}
}
}
return c;
}
mat pow (mat a,ll n)
{
mat b;
b.m[0][0]=1,b.m[1][0]=1;
b.m[1][0]=1,b.m[1][1]=1;
while(n)
{
if(n%2) b=mul(a,b);
a=mul(a,a);
n>>=1;
}
return b;
}
int main() {
ll n;
scanf("%lld",&n);
printf("%d\n",n%2==0? -1:1);
return 0;
}
B | 小A的回文串 |
暴力,分别求出奇数回文串和偶数回文串最大的情况。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn=5*1e3+5;
char s[maxn];
int main()
{
scanf("%s",s);
int len=strlen(s);
int ans=0;
for (int i=0;i<len;i++)
{
int tlen=0;
while(tlen*2+1<=len&&s[(i+tlen+len)%len]==s[(i-tlen+len)%len]) tlen++;
ans=max(tlen*2-1,ans);
}
for (int i=0;i<len;i++)
{
int tlen=0;
if(s[i]==s[(i-1+len)%len])
{
while((tlen+1)*2<=len&&s[(i+tlen+len)%len]==s[(i-tlen-1+len)%len]) tlen++;
ans=max(ans,(tlen)*2);
}
}
printf("%d\n",ans);
return 0;
}
C | 小A买彩票 |
递推,类似于背包,dp[i][j]表示买i张彩票获得j元的方法数。
打个表存一下,然后输出即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=35;
ll ans;
ll a[50];
ll dp[35][125];
ll ansc[35];
ll ansp[35];
ll gcd (ll a,ll b)
{
return b==0? a:gcd(b,a%b);
}
int main()
{
ansc[0]=ansp[0]=1;
a[0]=1;
for (int i=1;i<=30;i++) a[i]=a[i-1]*4;
memset (dp,0,sizeof(dp));
dp[1][1]=dp[1][2]=dp[1][3]=dp[1][4]=1;
for (int i=2;i<=30;i++)
{
for (int j=1;j<=120;j++)
{
if(dp[i-1][j])
{
for (int k=1;k<=4;k++)
{
dp[i][j+k]+=dp[i-1][j];
}
}
}
}
for (int i=1;i<=30;i++)
{
ll ans=0;
for (int j=120;j>=3*i;j--)
{
ans+=dp[i][j];
}
ll G=gcd(ans,a[i]);
ansc[i]=ans/G,ansp[i]=a[i]/G;
}
int n;
scanf("%d",&n);
printf("%lld/%lld\n",ansc[n],ansp[n]);
return 0;
}
D | 小A的位运算 |
维护前缀和和后缀和,然后求i-1的前缀或和i+1的后缀或或起来即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5*1e6+5;
int n;
ll a[maxn];
ll h[maxn];
ll t[maxn];
ll ans;
int main()
{
ans=0;
h[0]=0;
scanf("%d",&n);
t[n+1]=0;
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
h[i]=h[i-1]|a[i];
}
for (int i=n;i>=1;i--)
{
t[i]=t[i+1]|a[i];
}
for (int i=1;i<=n;i++)
{
ans=max(ans,h[i-1]|t[i+1]);
}
printf("%lld\n",ans);
return 0;
}