题解 2020/08/17 PJ组考试AK
\(T1\)
这怕不是一道贪心题吧。
容易想到我们找空的座位尽量长的地方放人。
然后,我们还要特殊地处理一下两侧。
剩下的细节稍微处理一下就好了。
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
register int Len;
register int S[100001];
cin>>Len;
register int i;
for(i=1;i<=Len;i++)
{
scanf("%1d",&S[i]);
}
register int Count;
Count=0;
register int Now;
Now=0;
register int Ling[100001],Start[100001];
register int Max;
Max=0;
Start[1]=1;
for(i=1;i<=Len;i++)
{
if(S[i]==0)
{
Now++;
}
else
{
Ling[++Count]=Now+1;
Now=0;
Start[Count+1]=i;
}
}
register int Ans,ans;
Ans=ans=0;
if(Now)Ling[++Count]=Now+1;
if(S[1]==0)Ans=(Ling[1]-1)/2;
for(i=2;i<=(S[Len]==0?Count-1:Count);i++)
if(Ling[i]/3>Ans)Ans=Ling[i]/3;
if(S[Len]==0&&Ans<(Ling[Count]-1)/2)Ans=(Ling[Count]-1)/2;
register int Pos;
if(S[1]==0)
{
ans=Ling[1]-1;
Pos=1;
}
for(i=2;i<=(S[Len]==0?Count-1:Count);i++)
{
if(Ling[i]/2>ans)
{
ans=Ling[i]/2;
Pos=Start[i]+Ling[i]/2;
}
}
if(S[Len]==0&&ans<Ling[Count]-1)
{
ans=Ling[Count]-1;
Pos=Len;
}
S[Pos]=1;
memset(Ling,0,sizeof(Ling));
memset(Start,0,sizeof(Start));
Start[1]=1;
register int Sum;
Sum=Count=0;
for(i=1;i<=Len;i++)
{
if(S[i]==0)
{
Sum++;
}
else
{
Ling[++Count]=Sum+1;
Start[Count+1]=i;
Sum=0;
}
}
if(Sum)
{
Ling[++Count]=Sum+1;
}
ans=Pos=0;
if(S[1]==0)
{
ans=Ling[1]-1;
Pos=1;
}
for(i=2;i<=(S[Len]==0?Count-1:Count);i++)
{
if(Ling[i]/2>ans)
{
ans=Ling[i]/2;
Pos=Start[i]+Ling[i]/2;
}
}
if(S[Len]==0&&ans<Ling[Count]-1)
{
ans=Ling[Count]-1;
Pos=Len;
}
S[Pos]=1;
for(i=2;i<=(S[Len]==0?Count-1:Count);i++)
{
ans=min(ans,Ling[i]);
}
cout<<max(ans,Ans)<<endl;
return 0;
}
\(T2\)
这怕不是一道小学数学题吧。
只不过是有很多鬼畜的数据而已。
所以,我们现在要考虑一些特殊情况。
- \(H=0\)时,答案为\(0\)。
- \(A<=B\)时,答案为\(1\)。
- \(B<=C\)时,无解。
然后,我还是来说一下普通情况的公式吧。
\[Days=\biggl\lceil\frac{A-B}{B-C}\biggr\rceil+1
\]
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
register int Case;
cin>>Case;
while(Case--)
{
register int A,B,C;
cin>>A>>B>>C;
if(A>0&&B<=C&&A>B)
{
cout<<"error"<<endl;
}
else
{
if(A==0)
{
cout<<0<<endl;
}
else
{
if(A<=B)
{
cout<<1<<endl;
}
else
{
cout<<(int)ceil(1.0*(A-B)/(B-C))+1<<endl;
}
}
}
}
return 0;
}
\(T3\)
这是一道数学题吧。
首先,我们很容易想到,我们只是要将\(B-A\)转换成\(±1±2±3\ldots±k\)。
然后,显然\(1+2+3\ldots+k\)要大于等于\(B-A\)。
其次,大家感性理解一下,\(1+2+3\ldots+k\)要和\(B-A\)奇偶性相同。
谁来教我怎么证明啊!
#include<bits/stdc++.h>
using namespace std;
long long A,B,Cha;
int main(void)
{
register int Case;
cin>>Case;
while(Case--)
{
cin>>A>>B;
Cha=abs(A-B);
if(Cha==0)
{
cout<<0<<endl;
continue;
}
register long long i;
register long long Sum;
Sum=0;
i=1;
while(true)
{
Sum+=i;
if(Sum>=Cha&&!((Sum^Cha)&1))
{
break;
}
i++;
}
cout<<i<<endl;
}
return 0;
}
\(T4\)
这其实一道非常烦的模拟题。
我们以第一种情况为例。
它有可能竖着插下去,一共有\(Column\)种情况。
还有可能横着放下去,前提是四个柱子一样高。
同理,我们即可求出每种方块的方案数量。
#include<bits/stdc++.h>
using namespace std;
int Column,Number;
int Array[101];
int main(void)
{
register int i,j;
cin>>Column>>Number;
register int Ans;
Ans=0;
for(i=1;i<=Column;i++)
{
cin>>Array[i];
}
switch(Number)
{
case 1:
{
Ans=Column;
for(i=1;i<=Column-3;i++)
{
if(Array[i]==Array[i+1]&&Array[i]==Array[i+2]&&Array[i]==Array[i+3])
{
Ans++;
}
}
break;
}
case 2:
{
Ans=0;
for(i=1;i<Column;i++)
{
if(Array[i]==Array[i+1])
{
Ans++;
}
}
break;
}
case 3:
{
Ans=0;
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+1]&&Array[i]+1==Array[i+2])
{
Ans++;
}
}
for(i=1;i<Column;i++)
{
if(Array[i]==Array[i+1]+1)
{
Ans++;
}
}
break;
}
case 4:
{
Ans=0;
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+1]+1&&Array[i+1]==Array[i+2])
{
Ans++;
}
}
for(i=1;i<Column;i++)
{
if(Array[i]+1==Array[i+1])
{
Ans++;
}
}
break;
}
case 5:
{
Ans=0;
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+1]&&Array[i]==Array[i+2])
{
Ans++;
}
}
for(i=1;i<Column;i++)
{
if(Array[i]==Array[i+1]+1)
{
Ans++;
}
}
for(i=1;i<Column;i++)
{
if(Array[i]+1==Array[i+1])
{
Ans++;
}
}
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+2]&&Array[i]==Array[i+1]+1)
{
Ans++;
}
}
break;
}
case 6:
{
Ans=0;
for(i=1;i<Column;i++)
{
if(Array[i]==Array[i+1])
{
Ans++;
}
}
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+1]&&Array[i]==Array[i+2])
{
Ans++;
}
}
for(i=1;i<=Column-2;i++)
{
if(Array[i]+1==Array[i+1]&&Array[i+1]==Array[i+2])
{
Ans++;
}
}
for(i=1;i<Column;i++)
{
if(Array[i]==Array[i+1]+2)
{
Ans++;
}
}
break;
}
case 7:
{
Ans=0;
for(i=1;i<Column;i++)
{
if(Array[i]==Array[i+1])
{
Ans++;
}
}
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+1]&&Array[i]==Array[i+2])
{
Ans++;
}
}
for(i=1;i<=Column-2;i++)
{
if(Array[i]==Array[i+1]&&Array[i+1]==Array[i+2]+1)
{
Ans++;
}
}
for(i=1;i<Column;i++)
{
if(Array[i]+2==Array[i+1])
{
Ans++;
}
}
break;
}
}
cout<<Ans<<endl;
return 0;
}
不要妄图追上西坠的太阳,而是要在黎明前就等着它!