作为一只菜鸡,这可能是我OI生涯中最后一次打百度之星了,希望明年这个时候能不退役(虽然不大可能)
开始贴题解吧。会持续更新。
1001 Arithmetic of Bomb
煞笔模拟题,1A
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+5;
const int mo=1e9+7;
int n,m;
char s[N],s1[N],ch[N],s2[N];
int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%s",s);
int len=strlen(s),m=0,i=0;
while (i<=len-1)
{
if (s[i]=='(')
{
int cnt=0;
i++;
while (s[i]!=')')
{
ch[++cnt]=s[i];
i++;
}
i+=3;
int cnt1=0;
while (s[i]!=')')
{
s2[++cnt1]=s[i];
i++;
}
int tim=0,c=1;
fd(j,cnt1,1)tim=(tim+1ll*(s2[j]-'0')*c%mo)%mo,c=1ll*c*10%mo;
while (tim--)
{
fo(j,1,cnt)s1[++m]=ch[j];
}
i++;
}
else
{
s1[++m]=s[i];
i++;
}
}
int ans=0,c=1;
fd(i,m,1)
{
ans=(ans+1ll*(s1[i]-'0')*c%mo)%mo;
c=1ll*c*10%mo;
}
printf("%d\n",ans);
}
}
1002
此题目前为止也只有6个人,一开始没注意到原来展开也可以是个int以内的数,直接像1001展开1e9就炸了= =要用快速幂合并,其实快速幂挺容易想到,但是整个题就是这个合并,是个码农题。口头ACqwq。
1003
蓝桥杯原题,统计原理,打个表一切就出来了,要注意的是从边角出发和从中间出发步数不一样,不能随便不经思考下结论。
http://blog.csdn.net/yanghui07216/article/details/50490089
#include
#include
#include
#define ll long long
#define M 1000000007
using namespace std;
ll a[200010];
ll b[20010];
int main()
{
int n,i;
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d",&n);
b[1]=1;
for(i=2;i<=n;i++)
b[i]=(b[i-1]*2%M);
a[1]=1;a[2]=6;
for(i=3;i<=n;i++)
a[i]=(b[i]+2*a[i-1]+4*a[i-2])%M;
ll sum=4*a[n];
for(i=2;i8*a[n-i]*b[i-1])%M+8*b[n-i]*a[i-1])%M)%M;
sum%=M;
}
if(n==1)
sum=2;
printf("%lld\n",sum);
}
return 0;
}
1004 留坑,不会做
1005数位dp,很久没打各种被坑,爽的一匹。
记录dp[i][j][k]表示做到第i位,前一个数为j,k表示前面是递增还是不递增,0/1状态。
记忆化搜索,由于很久没做过数位dp很多细节都忘记了,现在重新回顾一下,dalao可以跳过。
假如现在是递增状态,那么当前位的数必须是pre到当前位能取的最高数,设为end,那么明显,假如前一位未取满,那么这一位end随便搞,否则就不能超过原字符串中的数字。
假如不是,那么枚举他是否转移到递增状态,转移到很简单。
如果不转移,还是不递增,那么正常转移,当然,有一种特殊情况,就是前一位是0,这一位还是0,这种情况要打标记特殊处理,相当于直接全部为0。
最后我们对于不限制的情况用dp数组存一下,受限制的情况用dfs算就好了
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=205;
const int mo=1e9+7;
typedef long long ll;
ll dp[N][15][5];
ll p[N];
int num[N];
inline ll dfs(int pos,int status,int pre,int limit)
{
if (pos<1)return 1;
if (!limit&&dp[pos][pre][status]!=-1)
return dp[pos][pre][status];
int end=limit?num[pos]:9;
ll ans=0;
if(status)
{
fo(i,pre,end)
{
ans+=dfs(pos-1,status,i,limit&&i==end);
ans%=mo;
}
}
else
{
fo(i,0,end)
{
if (i>pre)
ans=(ans+dfs(pos-1,1,i,limit&&i==end))%mo;
else
{
if (!i&&pre==10)ans+=dfs(pos-1,0,10,limit&&i==end);
else ans+=dfs(pos-1,0,i,limit&&i==end);
ans%=mo;
}
}
}
if (!limit)dp[pos][pre][status]=ans;
return ans;
}
inline ll solve(char s[])
{
int len=strlen(s);
fo(i,0,len-1)
{
num[len-i]=s[i]-'0';
}
return dfs(len,0,10,1);
}
int main()
{
char s[N];
memset(dp,-1,sizeof(dp));
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%s",s);
printf("%lld\n",solve(s)-1);
}
}
1006 题解tag是折半状压网络流
不存在的,不会。留坑也填不了。