您的位置:首页 > 大数据 > 人工智能

2018 BUPT Winter Training #1 div.1

2018-01-30 18:44 441 查看
修电脑回来已经三点了…如果多一个半小时应该能够多写一题两题的,说到底还是水平太菜..

可能有空会补C.E.X三道题,G题待定

A - One Bomb

题意 只有一个炸弹可以消去i行j列上的所有的墙,问能否消去所有的墙。

思路:统计行列wall总数,在(i,j)上放置一个炸弹,iswall表示二元谓词判断(i,j)是否是墙,消去的墙的数目des=row[i]+col[j]−iswall(i,j)

#include <cstdio>
char map[1005][1005];
int r[1005]={0},c[1005]={0};
int main(){
int n,m,ar=0,ac=0,tot=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",map[i]+1);
for(int j=1;map[i][j];j++){
if(map[i][j]=='*'){
r[i]++;
c[j]++;
tot++;
}
}
}
for(int i=1;i<=n&&!ar;i++){
for(int j=1;j<=m&&!ar;j++){
if(r[i]+c[j]-(map[i][j]=='*')==tot)ar=i,ac=j;
}
}
if(ar)printf("YES\n%d %d",ar,ac);
else printf ("NO");
}


B -Vacations

每天给一个数字:0.只能休息(我们假设这相当于在第i个位置填入0,以下同理);1.可以填入1;2.可以填入2;3.既可以填入1也可以填入2。

要求1和2不能相邻

那么相当于求一个字符串,这个字符串中0的数目最少,问最少的0的数目。

这就是经典的字符串动态规划问题了:

设dp[i][j]是在第i个位置填入数字j时不是0的最大总数.那么

dp[i][0]=max(dp[i−1][0],dp[i−1][1],dp[i−1][2])dp[i][1 or 2]={maxdp(dp[i−1][0],dp[i−1][2 or 1])+1 可以做别的事[i][0] 只能休息

#include <cstdio>
#include <algorithm>
using namespace std;
int dp[105][3]={0};
int main(){
int n,toda;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&toda);
if(toda==1||toda==3)dp[i][2]=max(dp[i-1][1],dp[i-1][0])+1;
if(toda==2||toda==3)dp[i][1]=max(dp[i-1][2],dp[i-1][0])+1;
dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],dp[i-1][2]));
if(toda==0)dp[i][1]=dp[i][2]=dp[i][0];
}
printf("%d",n-max(dp
[0],max(dp
[1],dp
[2])));
}


D - Lorenzo Von Matterhorn

这里编码的完全二叉树有一个特点:

设父节点k=(a1a2a3...ap)2则左孩子为(a1a2a3...ap1)2右孩子为(a1a2a3...ap0)2那么设孩子节点k=(a1a2a3...ap)2有父节点一定为k=(a1a2a3...ap−1)2

#include <iostream>
#include <map>
typedef long long ll;
using namespace std;
map<ll,ll> tree;
int main(){
ios::sync_with_stdio(false);
int p,a,b;ll s,u,v,w,ans;
cin>>p;
while(p--){
cin>>s>>u>>v;
w=ans=0;
if(s==1)cin>>w;
while(u!=v){
if(u>v)ans+=(tree[u]+=w),u>>=1;
else ans+=(tree[v]+=w),v>>=1;
}
if(s==2)cout<<ans<<endl;
}
}


F - PLEASE

设三个概率分别为ln,mn,rn

根据对称性有ln=rn

根据概率性质有ln+rn+mn=1即ln=rn=1−mn2

所以mn=12ln−1+12rn−1=ln−1=1−mn−12

设分子为an,分母为bn,有mn=anbn,且a0=1,b1=1

代入上式得anbn=bn−1−an−12bn−1

易知bn=2n−1,an+an−1=bn−1=2n−2

设an+x2n−1=−(an−1+x2n−2),得x=−13,设cn=an+x2n−1,得:

an−132n−1=−13(−1)n−1

整理得到最终结果:

an=13(2n−1−(−1)n−1)

数学推导完毕,现在是数据的求法:

设常数2关于1e9+7的逆元i2,常数3关于1e9+7的逆元i3.谓词函数isodd(i)

有:2n=2∑an%mod,这里的an是题目所给的数组,bn=2n/2%mod=i2⋅2n%modan=13(bn−(−1)n−1)%mod=i3⋅(bn+1−2isodd(n))%mod

#include <iostream>
#define mo 1000000007
#define i3 333333336
#define i2 500000004
using namespace std;
typedef long long ll;
ll ar[100005];
ll qp(ll x,ll y){ll a=1;while(y){if(y&1)a=a*x%mo;x=x*x%mo;y>>=1;}return a;}
int main(){
ios::sync_with_stdio(false);
int n,flag=0,odd=1;ll a=1,b=2,base,t;
cin>>n;
for(int i=0;i<n;i++){
cin>>ar[i];
if(ar[i]>1)flag=1;
if(odd)odd&=ar[i]&1;
}
for(int i=0;i<n&&flag;i++)b=qp(b,ar[i]);
b=b*
ba6f
i2%mo;
cout<<(b+mo+1-(odd<<1))*i3%mo<<"/"<<b<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: