7.10noip测试

第一题:饼干

题意:有一(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 1000003
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;
}
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 double
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;
}
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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值