atcoder ABC129

C

  • 题意:爬楼梯,每次爬1~2层,有些层不能爬
  • 题解:斐波那契数列(标数法)递推
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=100005;
const int mod=1e9+7;
int n,m,num[maxn];
bool flag[maxn];
int main()
{
	int n,m; scanf("%d%d",&n,&m);
	for(int i=1,u;i<=m;++i) scanf("%d",&u),flag[u]=1;
	if(!flag[1]&&!flag[2]) {num[1]=1; num[2]=2;}
	else if(flag[1]&&!flag[2]) num[2]=1;
	else if(flag[1]&&flag[2]) {puts("0"); return 0;}
	for(int i=3;i<=n;++i)
		if(!flag[i]) num[i]=((long long)num[i-1]+num[i-2])%mod;
	cout<<num[n]<<endl;
	return 0;
}

D

  • 题意:n*m网格中有一些障碍,你有一盏灯,放下后照亮所在行,列未被障碍物遮挡的位置
  • 题解:两个数组分别统计[i][j]处放灯价值(rows,columns)数组,输出一下就知道,最后行列和求最大值
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=2005;
int n,m,lastr,lastc[maxn],rows[maxn][maxn],columns[maxn][maxn],ans;
int max(int a,int b){return a>b?a:b;}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		lastr=0; char temp=getchar();
		for(int j=1;j<=m;++j)
		{
			char temp=getchar();
			if(temp=='#')
			{
				for(int k=lastr+1;k<j;++k) rows[i][k]=j-lastr-1;
				for(int k=lastc[j]+1;k<i;++k) columns[k][j]=i-lastc[j]-1;
				lastr=j; lastc[j]=i;
			}
		}
		for(int k=lastr+1;k<=m;++k) rows[i][k]=m-lastr;
	}
	for(int i=1;i<=m;++i)
		for(int k=lastc[i]+1;k<=n;++k) columns[k][i]=n-lastc[i];
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j) ans=max(ans,rows[i][j]+columns[i][j]);
	cout<<ans-1<<endl;
	return 0;
}

E

  • 题意:给出一个二进制表示的L,满足题目的两个式子
  • 题解:不难发现a,b两个数二进制表示时同一位不同时为1时满足条件,题目变为排列组合
  • 举例:L=(1001011)2,方案数=3^6+2*(3^3+2*(3^0+2));
#include <iostream>
#include <cstdio>
using namespace std;
const int mod=1e9+7;
string a;
int len;
long long ans,three=1;
int main()
{
	cin>>a; len=a.length(); a=' '+a;
	while(len--)
	{
		if(a[len+1]=='1') {ans=(three+2)%mod; break;}
		three=(three*3)%mod;
	}
	three=(three*3)%mod;
	while(len--)
	{
		if(a[len+1]=='1') ans=(ans*2+three)%mod;
		three=(three*3)%mod;
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2020-10-12 17:10  wuwendongxi  阅读(160)  评论(0编辑  收藏  举报