渔王还想 继续做渔王大石碎胸口——万能青年旅店
久违的头图
而海港已经 不知去向
此刻他醉倒 在洗浴中心
没有潮汐的梦
胸口已暮色苍茫
肥胖的城市 递给他一个
传统的方法 来克制恐慌
卖掉武器 风暴喉咙
换取饮食
背叛能让你获得自由
停电之后 暂时摆脱了
坚硬的时刻 倒转的河
肥胖的城市
驱赶着所有 拒绝沉没的人
那首疯狂的歌又响起
电灯熄灭 物换星移 泥牛入海
黑暗好像 一颗巨石 按在胸口
独脚大盗 百万富翁 摸爬滚打
黑暗好像 一颗巨石 按在胸口
高一高考集训欢乐赛
少有的 IOI 赛制。
雀食唐氏,和名字一样。
赛时榜
T1 Efim与奇怪的成绩
模拟。
只是注意几个点:
- 只能在小数部分进位;
- 输出时不要后缀 \(0\) 和小数点;
- 注意在整数部分的进位。
主要思想是,进位的位置越靠前越大,然后轻松在第 3 个小时才打出来,主要是既没大样例又看不到测试点,到了不得不去想那 WA 掉的 15 分时才绞尽脑汁想到整数的进位问题。
code:
namespace Wisadel
{
short main()
{
cin>>n>>m;
scanf("%s",ss+1);
while(k<=n&&ss[k]!='.')k++;
//找到小数点
int i=k+1;
for(;i<=n;)
{
if(!m)
break;
int num=ss[i]-'0';
if(num>=5)
{//能进位就进
int pp=i,sds=i;
while(pp<=n)
ss[pp++]=0;
//后面全部不要
n=sds;m--;
//更新现在实数的长度 剩余的次数
if(--i==k)
{//小数部分没了
//因为整数部分不可四舍五入 所以无论如何要结束循环
ss[i]=0;
if(ss[i-1]=='9')
{//多重进位
while(--i>0&&ss[i]=='9')
ss[i]='0';
//都变成0
if(i==0)
{//全部都进一 然后没了 也就是整数部分都是9
printf("1");
printf("%s\n",ss+1);
//把多的1输出来 然后输出后面的0
return Ratio;
}
else
{
ss[i]++;
printf("%s\n",ss+1);
//不全是9 直接进位后输出
return Ratio;
}
}
else
ss[--i]++;
break;
}
else
{
ss[i]++;
i=k+1;
//没到整数部分,那么从十分位再次循环寻找进位机会
continue;
}
}
i++;
}
while(k<=n&&(ss[n]=='0'||ss[n]=='.'))
ss[n--]=0;
//去除后缀0和.
cout<<ss+1;
return Ratio;
}
}
T2 美丽的IP地址
暴搜就行,不过。。。
所以仙姑。
T3 装饰
仅有的好切的水题。
感觉下发的题解少有的讲得清楚。就是当三种颜色没有一种特别多(指超过其他两种颜色的 2 倍)时,都可以通过补凑的方法补齐,此时答案为 \(\frac{a+b+c}{2}\) 。
当存在上述一种特别多的颜色时,无论如何补凑都只能达到 \(a+b\) (我们假设 \(a\le b\le c\) ),也就是此时的答案。
注意 long long
。
code:
namespace Wisadel
{
void Wmov()
{
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
}
short main()
{
int T=qr;
while(T--)
{
a=qr,b=qr,c=qr;
Wmov();
if(a==0&&b==0)
printf("0\n");
else if(c>2*(a+b))
printf("%lld\n",a+b);
else printf("%lld\n",(a+b+c)/3);
}
return Ratio;
}
}
T4 大子矩阵Largest Submatrix
出生题,搜就完了。
真是醇搜啊,想了单调栈和坐标 dp,最后还真是暴力。
感谢 PEP 提供的借鉴。
code:
namespace Wisadel
{
bool Wck(int i,int j,int x,int y)
{
if(dh[i][j]==dh[x][y]||(dh[i][j]=='a'||dh[i][j]=='b')&&dh[x][y]=='w'||(dh[i][j]=='b'||dh[i][j]=='c')&&dh[x][y]=='x'||(dh[i][j]=='b'||dh[i][j]=='c'||dh[i][j]=='a')&&dh[x][y]=='z'||(dh[i][j]=='c'||dh[i][j]=='a')&&dh[x][y]=='y')return true;
if(dh[x][y]==dh[i][j]||(dh[x][y]=='a'||dh[x][y]=='b')&&dh[i][j]=='w'||(dh[x][y]=='b'||dh[x][y]=='c')&&dh[i][j]=='x'||(dh[x][y]=='b'||dh[x][y]=='c'||dh[x][y]=='a')&&dh[i][j]=='z'||(dh[x][y]=='c'||dh[x][y]=='a')&&dh[i][j]=='y')return true;
return false;
}
void W(int i,int j)
{
ll sumi=1;
fo(k,j+1,m)
if(Wck(i,j,i,k))
sumi++;
else break;
ans=max(ans,sumi);
ll sumj = 1;
fo(k,i+1,n)
if(Wck(i,j,k,j))
sumj++;
else break;
ans=max(ans,sumj);
ll mi=sumi;
fo(ii,i+1,sumj+i-1)
{
ll sum=1;
fo(jj,j+1,sumi+j-1)
if(Wck(i,j,ii,jj))
sum++;
else break;
mi=min(mi,sum);
ans=max(ans,mi*(ii-i+1));
}
}
short main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dh,0,sizeof dh);
ans=0;
fo(i,1,n)
fo(j,1,m)
cin>>dh[i][j];
fo(i,1,n)
fo(j,1,m)
if(dh[i][j]=='w')
{
dh[i][j]='a';W(i,j);
dh[i][j]='b';W(i,j);
dh[i][j]='w';
}
else if(dh[i][j]=='y')
{
dh[i][j]='a';W(i,j);
dh[i][j]='c';W(i,j);
dh[i][j]='y';
}
else if(dh[i][j]=='z')
{
dh[i][j]='a';W(i,j);
dh[i][j]='b';W(i,j);
dh[i][j]='c';W(i,j);
dh[i][j]='z';
}
else if(dh[i][j]=='x')
{
dh[i][j]='b';W(i,j);
dh[i][j]='c';W(i,j);
dh[i][j]='x';
}
else
W(i,j);
printf("%lld\n",ans);
}
return Ratio;
}
}
T5 中国象棋
有很多转移方程的 dp。
雀食像棋。
首先审题,得到一个关键结论:一行或一列中最多只能有两个炮。
那么为了确定场上时刻的局势,我们令 \(f_{i,j,k}\) 为转移到第 \(i\) 行,有 \(j\) 列含有一个炮,\(k\) 列含有两个炮,那么可知,\(m-j-k\) 列没有炮。
我们按放炮的方式推。每行最多放两个炮,那么会有三种情况。
一,不放炮,由上一行的情况直接转移。
\[f_{i,j,k}=f_{i-1,j,k} \]二,放一个炮,那么又会有两种情况,一种是放在没有炮的列上,一种是放在有一个炮的列上。
\[f_{i,j,k}+=f_{i-1,j-1,k}\times (m-j-k+1) \quad(j\ge 1) \]\[f_{i,j,k}+=f_{i-1,j+1,k-1}\times (j+1) \quad(k\ge 1) \]三,放两个炮,有三种情况,一是都放在没有炮的列上,二是一个放在有一个炮的列上,另一个放在没有炮的列上,三是两个都放在有一个炮的列上。
\[f_{i,j,k}+=f_{i-1,j-2,k}\times C(m-j-k+2,2) \quad(j\ge 2) \]\[f_{i,j,k}+=f_{i-1,j,k-1}\times j\times (m-j-k+1) \quad (k\ge 1) \]\[f_{i,j,k}+=f_{i-1,j+2,k-2}\times C(j+2,2) \quad(k\ge 2) \]这里 \(C(n,m)\) 为组合数。
边界为 \(f_{0,0,0}=1\),最后答案是\(\sum_{0\le i\le m,0\le j\le m}f_{n,i,j}\pmod {9999973}\)。
注意 long long
。
code:
namespace Wisadel
{
int C(int x,int y)
{
return ((x*(x-1))/y)%mod;
}
short main()
{
n=qr,m=qr;
zl[0][0][0]=1;
fo(i,1,n)//行
//一行最多放两个炮
fo(j,0,m)//一个炮列
fo(k,0,m-j)//两个炮列
{
zl[i][j][k]=zl[i-1][j][k];//这一行不放炮
//两个炮的列++
if(k>=2)
zl[i][j][k]+=zl[i-1][j+2][k-2]*C(j+2,2);//在两个1炮列上放
if(k>=1)
zl[i][j][k]+=zl[i-1][j+1][k-1]*(j+1),//在一个1炮列上放
zl[i][j][k]+=zl[i-1][j][k-1]*j*(m-j-k+1);//在没有炮的列上放
//一个炮的列++
if(j>=1)
zl[i][j][k]+=zl[i-1][j-1][k]*(m-j-k+1);//放在没炮的列
if(j>=2)
zl[i][j][k]+=zl[i-1][j-2][k]*C(m-j-k+2,2);//放在两个没炮的列
zl[i][j][k]%=mod;
}
fo(i,0,m)
fo(j,0,m)
ans=(ans+zl[n][i][j])%mod;
printf("%lld\n",(ans+mod)%mod);
return Ratio;
}
}
T6 奇妙的 Fibonacci
雀食奇妙,还没有人 AC。