7.10noip测试

来源:互联网 发布:电脑压力测试软件 编辑:程序博客网 时间:2024/05/25 01:36

第一题:饼干

题意:有一(2^n)*(2^n)的矩阵,每次可选一范围2^k使其右上角铺满饼干(k>=2)。求最少有几块不能被覆盖。

题解:自己画图,丰衣足食。(答案即3^(n-1))

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define mod 1000003using namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int n;long long fast(long long a,long long b){long long ret=1;while(b){if(b&1)ret=(ret*a)%mod;a=(a*a)%mod;b>>=1;}return ret;}signed main(){n=read();cout<<fast(3,n-1);return 0;}
第二题:鸭舌

题意:n点树,i节点有ai个鸭舌,从给定节点x出发,每到一点该点鸭舌-1,无鸭舌不行,欲返x,求至多能食之舌几何。

题解:大家都知道这必须是一个树形DP,以x为根,能走子树先走子树。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<vector>using namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}long long dp[101101],a[101101],mini[101101];int n,aa,b,tot,nxt[202202],first[101101],goal[202202],x;void addedge(int a,int b){++tot;nxt[tot]=first[a];first[a]=tot;goal[tot]=b;++tot;nxt[tot]=first[b];first[b]=tot;goal[tot]=a;return ;}void dfs(int pos,int fa){dp[pos]=1;vector<long long>que;for(int p=first[pos];p;p=nxt[p])if(goal[p]!=fa&&a[goal[p]]){--a[goal[p]];dfs(goal[p],pos);if(dp[goal[p]]) que.push_back(dp[goal[p]]);}sort(que.begin(),que.end());for(int i=que.size()-1;a[pos]&&i>=0;--i)--a[pos],dp[pos]+=que[i]+1;for(int p=first[pos];a[pos]&&p;p=nxt[p])if(goal[p]!=fa&&a[goal[p]]){dp[pos]+=min(a[pos],a[goal[p]])*2;a[pos]-=min(a[pos],a[goal[p]]);}return ;}signed main(){n=read();for(int i=1;i<=n;++i)a[i]=read();for(int i=1;i<n;++i){aa=read();b=read();addedge(aa,b);}x=read();dfs(x,0);cout<<dp[x]-1;return 0;}
第三题:路径
题意:n*m图,有障碍,障碍周围8格无障碍,每行每列仅一障碍,求两点距离之平均。

题解:见代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define int long long#define double long doubleusing namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int n,m,transverse[1010],vertical[1010],robl,squ;double ans;char s[1010][1010];long long cal(int n,int m,int *se){int ret=0;for(int i=1;i<=n;++i){int plus=0,place=m-se[i];for(int j=1;j<=n;++j)if(i!=j){if(se[j])plus+=(long long)(m-1)*abs(i-j);else plus+=(long long)m*abs(i-j);}if(se[i]) ret+=plus*(m-1);else ret+=plus*m;int lef=i-1,righ=i+1;if(se[i]){while(se[lef]>se[lef+1]){place+=m-se[lef];--lef;}while(se[righ]>se[righ+1]){place+=m-se[righ];++righ;}ret+=4*(se[i]-1)*place;}}return ret;}signed main(){n=read();m=read();for(int i=1;i<=n;++i)scanf("%s",s[i]+1);for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(s[i][j]=='X'){transverse[i]=j;vertical[j]=i;++robl;}squ=n*m-robl;ans=(double)(cal(n,m,transverse)+cal(m,n,vertical))/(squ*squ);printf("%.6Lf",ans);return 0;}