https://www.nowcoder.com/acm/contest/189#question
A.数字权重
小a有一个n位的数字,但是它忘了各个位上的数是什么,现在请你来确定各个位上的数字,满足以下条件:
设第i位的数为ai,其中a1为最高位,an为最低位,K为给定的数字
1. 不含前导0
2.
请你求出满足条件的方案数
找规律的题
发现答案只和k有关,正数是9-k,负数是10+k,然后快速幂pow(10,n-2,mod)即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const int mod=1e9+7;
long long n,k;
int dp[20];
ll work(ll a,ll b)
{
ll ans=1;
while(b)
{
if (b&1)
{
ans=ans*a%mod;
}
a=a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
scanf("%lld%lld",&n,&k);
if (abs(k)>=10)
{
puts("0");
}
else
{
long long ans=0;
if (k>=0)
{
ans=(9-k)*work(10,n-2)%mod;
}
else
{
ans=(10+k)*work(10,n-2)%mod;
}
printf ("%lld\n",ans);
}
return 0;
}
B.毒瘤xor
小a有N个数a1, a2, ..., aN,给出q个询问,每次询问给出区间[L, R],现在请你找到一个数X,使得
1、
2、最大,表示异或操作(不懂的请自行百度)
对每一位进行前缀和
蒟蒻表示不懂,贴一发大神的代码
#include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt*2
#define rson mid+1,r,rt*2+1
const int N=1e5+7;
int n,a[N],s[31][N];
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=0; i<=30; i++)
{
for(int j=1; j<=n; j++)
{
s[i][j]=s[i][j-1]+((a[j]&(1<<i))!=0);
}
}
int Q,l,r,ans;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&l,&r);
ans=0;
for(int i=0; i<=30; i++)
if(2*(s[i][r]-s[i][l-1])<r-l+1)ans+=1<<i;
printf("%d\n",ans);
}
}
C.硬币游戏
有一天clccle在机房里和sarlendy玩游戏,游戏的规则是这样的,在clccle和sarlendy的面前有两行长度为2n的硬币序列,共4n枚硬币,从clccle开始取,每次只能取两个人之前都没取过的位置的硬币,如果所取硬币朝上(U)的话记为1,所取硬币朝下(D)的话记为0,这样n次后两个人就得到了长度为n的数字串,谁的数字大谁就赢了,当然也存在平局的情况,当然这两个人都非常的睿智,现在clccle想知道,Ta有没有必胜策略?如果有的话就输出“clccle trl!”,没有的话输出“sarlendy tql!”,特别的,平局输出“orz sarlendy!”。
水题,判断双U,UD,DU的次数就行了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,x;
char s1[2100001];
char s2[2100001];
int main()
{
scanf("%d",&n);
scanf("%s",s1);
scanf("%s",s2);
int a=0;
int b=0;
int c=0;
int d=0;
for(int i=0;i<n*2;i++)
{
if (s1[i]=='U'&&s2[i]=='U')
{
a++;
}
if (s1[i]=='U'&&s2[i]=='D')
{
b++;
}
if (s1[i]=='D'&&s2[i]=='U')
{
c++;
}
}
if (a*2==n)
{
puts("orz sarlendy!");
}
else if (a&1)
{
if (b>c-1)
{
puts("clccle trl!");
}
else if(b<c-1)
{
puts("arlendy tql!");
}
else
{
puts("rz sarlendy!");
}
}
else
{
if (b>c)
{
puts("clccle trl!");
}
else if(b<c)
{
puts("arlendy tql!");
}
else if (b==c)
{
puts("rz sarlendy!");
}
}
return 0;
}
D.粉樱花之恋
qn是个特别可爱的小哥哥,qy是个特别好的小姐姐,他们两个是一对好朋友 [ cp (划掉~)
又是一年嘤花烂漫时,小qn于是就邀请了qy去嘤花盛开的地方去玩。当qy和qn来到了田野里时,qy惊奇的发现,嘤花花瓣以肉眼可见的速度从树上长了出来。
仔细看看的话,花瓣实际上是以一定规律长出来的,而且,每次张成新的花瓣的时候,上一次的花瓣就会都落到地上,而且不会消失。
花瓣生长的规律是,当次数大于等于2时,第i次长出来的花瓣个数和上一次张出来的花瓣个数的差是斐波那契数列的第i-1项。初始的时候地上没有花瓣,树上的花瓣个数为1,第一次生长的花瓣个数为1。初始的那个花瓣就落到了地上
现在,小qn想知道,经过k次生长之后,树上和地上的总花瓣个数是多少?
ps:斐波那契数列:
f[1]=f[2]=1;f[i]=f[i-1]+f[i-2] (i>=2且i N+)
说白了就是求斐波那契数列前n项和,是f[n+2]-1
矩阵快速幂,我只拿数组水了60~~~
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define mod 998244353
#define maxn 2
using namespace std;
struct Matrix
{
long long m[maxn][maxn];//maxn是方阵的大小
}p,I,x;
Matrix matrixmul( Matrix a, Matrix b)
{
int i,j,k;
Matrix c;
for(i=0;i<maxn;i++)
for(j=0;j<maxn;j++)
{
c.m[i][j]=0;
for(k=0;k<maxn;k++)
c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;///mod 是要取模的值
c.m[i][j]%=mod;
}
return c;
}
Matrix quickpow(long long n)
{
Matrix m=p,b=I;///I 是单位矩阵
while(n>0)
{
if(n&1)
b=matrixmul(b,m);
n=n>>1;
m=matrixmul(m,m);
}
return b;
}
int main()
{
long long n;
scanf("%lld",&n);
I.m[0][0]=1;I.m[1][1]=1;
p.m[0][0]=1;p.m[0][1]=1;p.m[1][0]=1;
x=quickpow(n+1);
printf("%lld\n",(x.m[0][0]+x.m[0][1]-1)%mod);
return 0;
}
E.符合条件的整数
给定两个整数N,M,表示区间 [2N,2M),请求出在这个区间里有多少个整数i满足i % 7=1
当时没想到,其实很简单
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
ll n,m;
ll solve(ll n)
{
return ((ll)pow(2,n)-2)/7+1;
}
int main()
{
scanf("%lld%lld",&n,&m);
printf ("%lld\n",solve(m)-solve(n));
return 0;
}