半夜打的一场div2。赛前看到是一场六题的div2,以为上不了分了。结果居然是好的。
A:有幸看过LPL的比赛,所以对这个赛制还是非常了解的。冠军的队伍一直在胜者组,所以一场都不会输。其他队伍都被淘汰,所以每个队伍都输了两场。总的比赛数就是2*n-2。
B:非常好的一道构造题。可以发现如果永远走不出迷宫,那么一定是陷入了一个环中。可见最小的环是2,所以不存在kn-1的情况。其他情况,将不需要走出的位置,引导到这个二元环上;反之不引导到环上即可。
`cpp
inline void solve()
{
int n,k;
cin>>n>>k;
if(n*n-1k)
{
cout<<"No"<<endl;
return;
}
k=n*n-k;
cout<<"Yes"<<endl;
for(int i=1;i<=n;i++)
{
if(k>0)
{
if(i==1) cout<<"R";
else cout<<"L";
}
else
{
cout<<"D";
}
k--;
}
cout<<endl;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(k>0) cout<<"U";
else cout<<"D";
k--;
}
cout<<endl;
}
}
C:很巧妙的题啊!感觉这场的题都挺巧妙的。可以发现相邻的两个人最多相差1,所以每个人的状态都可以根据旁边人的状态推得。那么最终结果就只和第一个人所处的方向有关。
确定了第一个人的方向,线性推一边。最后统计一下,推出来的结果,是否满足第一个人需要看到的魔术师的数量即可。
inline void solve() { int n; cin>>n; vector<int> num(n+5); for(int i=1;i<=n;i++) { cin>>num[i]; } for(int i=2;i<=n;i++) { if(abs(num[i]-num[i-1])>=2) { cout<<0<<endl; return; } } int tf1=0,tf2=0; vector<int> st(n+5); st[1]=1; for(int i=2;i<=n;i++) { if(st[i-1]==1) { if(num[i]==num[i-1]) { st[i]=0; } else if(num[i]==num[i-1]-1) { st[i]=1; } else { tf1--; break; } } else//0 { if(num[i]==num[i-1]) { st[i]=1; } else if(num[i]==num[i-1]-1) { tf1--; break; } else { st[i]=0; } } } tf1++; if(tf1) { int sum=0; for(int i=2;i<=n;i++) { if(st[i]==1) sum++; } if(sum+1!=num[1]) tf1=0; } st[1]=0; for(int i=2;i<=n;i++) { if(st[i-1]==1) { if(num[i]==num[i-1]) { st[i]=0; } else if(num[i]==num[i-1]-1) { st[i]=1; } else { tf2--; break; } } else//0 { if(num[i]==num[i-1]) { st[i]=1; } else if(num[i]==num[i-1]-1) { tf2--; break; } else { st[i]=0; } } } tf2++; if(tf2) { int sum=0; for(int i=2;i<=n;i++) { if(st[i]==1) sum++; } if(sum+1!=num[1]) tf2=0; } cout<<tf1+tf2<<endl; }
D:卡了好久这道题,一直没想明白除了傻瓜一样暴力,还能怎么办。后来突发奇想如果a数量多的话,一定存在相邻的两个电池都是有电的。所以可以先遍历一遍相邻的组合,再遍历中间隔了一个的,隔了两个的……以此类推。大概想了一下肯定能过。并不知道怎么证明这个。
inline int ask(int x,int y) { cout<<x<<" "<<y<<endl; int re; cin>>re; return re; } inline void solve() { int n; cin>>n; for(int i=1;i<n;i++) { for(int j=1;j+i<=n;j++) { if(ask(j,j+i)) return; } } }
最后排了622,+56 。怒刷rating pr了!