Problem A(读信)
签到题:
把所有字母全部转换成大写(或小写), 然后判断一下是否是回文串(正着和倒着是否完全相等)就可以了
时间复杂度:
Problem B(Anxdada的询问1)
签到题:
for(int i=1;i<n;++i)
for(int j=i+1;j<=n;++j)
if(a[i]+a[j]==2*m)
++ans;
注意: 使用(a[i]+a[j])/2==m
可能会出问题: (int/int==int)
时间复杂度:
Problem C(Anxdada的询问2)
简单题:
考虑每一个数字
, 能和
组成平均数为
的数为
所以枚举每一个
, 统计一下数字
的个数就好了
统计数字个数:
解法1: C++STL库的map<int,int>
(由于牛客没有开O2优化, 所以很慢: 1300ms左右, 没有卡这种做法)
解法2: 二分查找
对数组
排序, 通过二分查找: 找到数组中第一个
的数字的下标
, 再通过二分查找出第一个
的数字的下标
,
就是数字
的出现次数
(快如闪电, 200ms左右)
注意: 为了避免重复计算, 由于平均数等于m的2个数一定: 其中一个
, 另外一个
, 所以统计
的一部分就好了, 再特殊处理一下
的情况
时间复杂度:
Problem E(mengxiang000的龙)
计算几何(初中数学):
相信大家都学过”将军饮马”问题, 这道题就是
借鉴来的
作: 家关于河流的对称点: 家’, 所以家’与学校的连线与河流的交点就是答案
做法1: 寄蒜几盒(计算几何)硬做, 时间复杂度
做法2: 推公式
(无损精度的公式如下)
答案就是
时间复杂度
做法3: 三分查极值(略), 时间复杂度
Problem F(fold的游戏)
思维题:
这道题直接输出: “plp win”就行了(想不到吧!)
证明:
设: 题目中的游戏为
我们对游戏
加上一个限制条件, 不能选1这个数字, 这样形成了一个新游戏
如果对于某一个确定的
, 游戏
一定存在某种策略, 要么先手必胜, 要么后手必胜
对于某一个确定的
, 游戏
如果先手必胜, 那么游戏
先手也一定能取得胜利, 因为1是所有数字的约数, 选中任意一个不为1的数字以后就不能再选1; 游戏
如果后手必胜, 那么游戏
的先手选1, 那么
的先手将变成游戏
的后手, 也能够取得胜利, 所以先手必胜
时间复杂度
Problem G(EL_PSY_CONGROO)
这道题就是在DAG(有向无环图)中找起点到终点的路径的条数
拓扑排序的过程中维护一下方案数+
注意: 答案取模(余)以后等于0, 答案不一定是不可达
Problem H(陈犇的数学题)
数学题:
这里的向下取整符号
是骗人的, 因为答案始终都是整数
由于 , 所以
由于答案对 取模(余), 所以当 时一定包含因子 , 此时答案为
当 时, 循环计算就可以了
由于有多个询问, 所以需要预处理出 阶乘, 然后 的回答每个询问就好了
时间复杂度
Problem J(twh233打方块)
模拟题:
处理出所有方块(及其旋转)的19种情况, 然后按照题意模拟即可
时间复杂度:
写就能过
标程:
#include<bits/stdc++.h>
using namespace std;
struct block
{
bool a[5][5];
int l,r;
block() {memset(a,0,sizeof(a));}
};
vector<block>G;
void make(int b,int c,int d,int e,int f,int g,int h,int i,int l,int r)
{
block x;
x.a[b][c]=1,x.a[d][e]=1;
x.a[f][g]=1,x.a[h][i]=1;
x.l=l,x.r=r;G.push_back(x);
}
void init()
{
make(1,1,1,2,1,3,1,4,1,4);
make(1,1,2,1,3,1,4,1,1,1);
make(1,1,2,1,2,2,2,3,1,3);
make(1,1,1,2,2,1,3,1,1,2);
make(1,1,1,2,1,3,2,3,1,3);
make(1,2,2,2,3,2,3,1,1,2);
make(2,1,2,2,2,3,1,3,1,3);
make(1,1,2,1,3,1,3,2,1,2);
make(1,1,1,2,1,3,2,1,1,3);
make(1,1,1,2,2,2,3,2,1,2);
make(1,1,1,2,2,1,2,2,1,2);
make(1,2,1,3,2,1,2,2,1,3);
make(1,1,2,1,2,2,3,2,1,2);
make(1,1,1,2,2,2,2,3,1,3);
make(1,2,2,1,2,2,3,1,1,2);
make(1,2,2,2,2,1,2,3,1,3);
make(1,2,2,1,2,2,3,2,1,2);
make(1,1,2,1,3,1,2,2,1,2);
make(1,1,1,2,1,3,2,2,1,3);
}
char a[20][15];
int down(int i,int j)
{
int l=j,r=j+G[i].r-1;
for(int k=1;;k++)
for(int x1=1,x2=k;x1<=4; x1++,x2++)
for(int y1=1,y2=l;y1<=G[i].r && y2<=r;y1++,y2++)
if(G[i].a[x1][y1] && a[x2][y2]=='#')
return k-1;
}
void add(int i,int j,int k,bool op)
{
int l=j,r=j+G[i].r-1;
for(int x1=1,x2=k;x1<=4; x1++,x2++)
for(int y1=1,y2=l;y1<=G[i].r && y2<=r;y1++,y2++)
if(G[i].a[x1][y1])
a[x2][y2]=op?'#':'*';
}
int cal()
{
int res=0;
for(int i=1;i<=15;i++)
{
bool flag=true;
for(int j=1;j<=10;j++)
if(a[i][j]=='*')
flag=false;
if(flag)res++;
}
return res;
}
int main()
{
init();
for(int i=1;i<=15;i++)scanf("%s",a[i]+1);
for(int i=1;i<=10;i++)a[16][i]='#';
int ans=0;
for(int i=0;i<G.size();i++)
for(int j=1;j+G[i].r<=11;j++)
{
int k=down(i,j);
add(i,j,k,true);
ans=max(ans,cal());
add(i,j,k,false);
}
return !printf("%d\n",ans);
}