CF1426 ABCDEF 数学+思维+DP

CF1426A 数学
题意:
第一层\(2\)间房间,之后每层\(x\)间房间,编号依次递增,求第\(n\)号房间在第几层
题解:

\[1+\lfloor\frac{max((n-2),0)}{m}\rfloor+(max((n-2),0)\%m>0) \]

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#define INF 1e9+7
#define ll long long
using namespace std;
int T,n,m,a,b,c,d;
void solve()
{
    scanf("%d%d",&n,&m);
    printf("%d\n",1+max((n-2),0)/m+(max((n-2),0)%m>0));
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
	  solve();
	}
	return 0;
}

CF1426B 思维
题意:
给定\(n\)\(2*2\)矩阵,求是否能通过这n个矩阵组成一个\(k*k\)的对称矩阵
题解:
首先\(k\)是奇数无解
只要存在一个对称矩阵,就一定能组成\(k*k\)对称矩阵

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#define INF 1e9+7
#define ll long long
using namespace std;
int T,n,m,a,b,c,d;
void solve()
{
    scanf("%d%d",&n,&m);
    int fl=0;
    for(int i=1;i<=n;i++)
    {
      scanf("%d%d%d%d",&a,&b,&c,&d);
      if(b==c)fl=1;
	}
	if(m%2)fl=0;
	printf(fl?"YES\n":"NO\n");
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
	  solve();
	}
	return 0;
}

CF1426C 数学+思维
题意:
你有两个操作
1:复制一个数
2:选择一个数,让它\(+1\)
求最少步数使得所有数的和\(\ge n\)
题解:

\[\frac{n}{\sqrt{n}}+\sqrt{n}+(n\%\sqrt{n}>0)-2 \]

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#define INF 1e9+7
#define ll long long
using namespace std;
int T,n;
void solve()
{
    scanf("%d",&n);
    int t=sqrt(n);
    printf("%d\n",n/t+t+(n%t>0)-2);
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
	  solve();
	}
	return 0;
}

CF1426D 思维
题意:
给定一个序列,你可以在其中任何位置插入任何值,问最少插入几个数使得序列不存在和为0的子序列
题解:
从前往后扫,找到一个等于0的子序列,在尾巴插入一个值,此时这个尾巴前的所有子序列都不可能等于0,将其断开,对后续序列继续做相同的事
找等于0的子序列可以通过前缀和,若一段子序列等于0,那么相同前缀和必定出现两次

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#define INF 1e9+7
#define ll long long
using namespace std;
int T,n,ans;
map <ll,int> fl;
void solve()
{
    scanf("%d",&n);
    ll a,sum=0;fl[0]=1;
    for(int i=1;i<=n;i++)
    {
      scanf("%lld",&a);
      sum+=a;
      if(fl[sum])
      {
        ans++;
        fl.clear();fl[0]=1;
        sum=a;
	  }
	  fl[sum]=1;
	}
	printf("%d\n",ans);
}
int main()
{
	//scanf("%d",&T);
	T=1;
	while(T--)
	{
	  solve();
	}
	return 0;
}

CF1426E 思维
题意:
已知两人石头剪刀布的各个出手数量,求alice的最多胜和最少胜
题解:
让alice尽可能赢或输
\(n-min(a,n-e)-min(b,n-f)-min(c,n-d)\)
\(min(a,e)+min(b,f)+min(c,d)\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#define INF 1e9+7
#define ll long long
using namespace std;
int T,n;
ll a,b,c,d,e,f;
void solve()
{
    scanf("%d%lld%lld%lld%lld%lld%lld",&n,&a,&b,&c,&d,&e,&f);
    printf("%lld %lld\n",n-min(a,n-e)-min(b,n-f)-min(c,n-d),min(a,e)+min(b,f)+min(c,d));
}
int main()
{
	//scanf("%d",&T);
	T=1;
	while(T--)
	{
	  solve();
	}
	return 0;
}

CF1426F DP
题意:
给定一个带有缺省的字符串,可以用abc代替?,求有多少个来自不同原串的abc子序列
题解:
\(f[i][0/1/2]\)表示前i个字符,为a/ab/abc的子序列有多少
\(cnt\)为前i个字符可以组成多少个不同串
则当\(ch[i]=='a'\)
\(f[i][0]=f[i-1][0]+cnt\)
\(f[i][1]=f[i-1][1]\)
\(f[i][2]=f[i-1][2]\)
\(ch[i]=='b'\)
\(f[i][0]=f[i-1][0]\)
\(f[i][1]=f[i-1][1]+f[i-1][0]\)
\(f[i][2]=f[i-1][2]\)
\(ch[i]=='c'\)
\(f[i][0]=f[i-1][0]\)
\(f[i][1]=f[i-1][1]\)
\(f[i][2]=f[i-1][2]+f[i-1][0]\)
\(ch[i]=='?'\)
\(f[i][0]=3*f[i-1][0]+cnt\)
\(f[i][1]=3*f[i-1][1]+f[i-1][0]\)
\(f[i][2]=3*f[i-1][2]+f[i-1][1]\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#define mod 1000000007
#define ll long long
using namespace std;
int T,n;
char ch[200001];
int f[200001][3],sm[200001][3];
void add(int &c,int a,int b){c=a+b;if(c>=mod)c-=mod;}
void work(int f0,int f1,int f2,int i)
{
	//printf("%d %d %d %d\n",f0,f1,f2,i);
	f[i+1][0]=(f[i][0]+f0)%mod;
	f[i+1][1]=(f[i][1]+f1)%mod;
	f[i+1][2]=(f[i][2]+f2)%mod;
	//printf("%d %d %d\n",f[i+1][0],f[i+1][1],f[i+1][2]);
}
void solve()
{
    scanf("%d%s",&n,ch);
    int cnt=1;
	for(int i=0;i<n;i++)
	{
	  if(ch[i]=='a')work(cnt,0,0,i);
	  else if(ch[i]=='b')work(0,f[i][0],0,i);
	  else if(ch[i]=='c')work(0,0,f[i][1],i);
	  else {work(((ll)2*f[i][0]+cnt)%mod,((ll)2*f[i][1]+f[i][0])%mod,((ll)2*f[i][2]+f[i][1])%mod,i);cnt=(ll)cnt*3%mod;}
	}
	printf("%d\n",f[n][2]);
}
int main()
{
	//scanf("%d",&T);
	T=1;
	while(T--)
	{
	  solve();
	}
	return 0;
}
posted @ 2020-10-20 09:16  worcher  阅读(129)  评论(0编辑  收藏  举报