tg 34 solution
T1
\(10pts:\)手玩即可有\(10\)分
\(30pts:\)朴素的\(O(n^2)\)模拟即可获得\(30pts\)
\(60pts:\)
\(1.\)在\(O(n^2)\)算法基础上选择卡常常数优化即可获得\(60pts\)
\(2.\)如果要优化最坏时间复杂度,考虑\(Splay\)维护区间
可以看做删除+区间平移,单次时间复杂度\(\log n\)
\(100pts:\)
正解显然是线性递推,我们考虑倒着插回去
正着顺时针,反着就是逆时针,于是各种减
首先人数和当前位置前移
然后删除的从上一个位置跳了\(i\)个
防止大量循环和减爆零就取个模
最后出的编号就是死的最早的那个,也就是\(1\)
点击查看代码
``` void work(){ int now=1,tot=1; for(int i=n-1;i;i--){ tot++,now++; now-=i%tot; if(now<=0)now+=tot; } ans=n-now+1; } ```T2
模拟
\(40pts:\)不用考虑高的问题,所有的操作等价于上下左右平移
\(100pts:\)维护下高指向的情况,考虑全变化就好了,总共\(6\)种但是懒得写了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int o=2222;
int c[o][o],k,n,x[o],y[o],shu,ans;
char ch[o];
void changeN(){
if(shu==2){
shu=0;
y[0]=max(y[k],y[1]);
for(int i=k;i>=1;i--){
y[i]=y[0]+1;
}
c[x[k]][y[k]]++;
ans=max(ans,c[x[k]][y[k]]);
}
else if(shu==1){
for(int i=1;i<=k;i++){
y[i]++;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
else{
shu=2;
for(int i=1;i<=k;i++){
y[i]=y[k]+i;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
}
void changeE(){
if(shu==1){
shu=0;
x[0]=max(x[k],x[1]);
for(int i=1;i<=k;i++){
x[i]=x[0]+1;
}
c[x[k]][y[k]]++;
ans=max(ans,c[x[k]][y[k]]);
}
else if(shu==2){
for(int i=1;i<=k;i++){
x[i]++;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
else{
shu=1;
for(int i=1;i<=k;i++){
x[i]=x[k]+i;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
}
void changeW(){
if(shu==1){
shu=0;
x[0]=min(x[k],x[1]);
for(int i=1;i<=k;i++){
x[i]=x[0]-1;
}
c[x[1]][y[1]]++;
ans=max(ans,c[x[1]][y[1]]);
}
else if(shu==2){
for(int i=1;i<=k;i++){
x[i]--;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
else{
shu=1;
for(int i=k;i>=1;i--){
x[i]=x[1]-i;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
}
void changeS(){
if(shu==2){
shu=0;
y[0]=min(y[k],y[1]);
for(int i=k;i>=1;i--){
y[i]=y[0]-1;
}
c[x[1]][y[1]]++;
ans=max(ans,c[x[1]][y[1]]);
}
else if(shu==1){
for(int i=1;i<=k;i++){
y[i]--;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
else{
shu=2;
for(int i=k;i>=1;i--){
y[i]=y[1]-i;
c[x[i]][y[i]]++;
ans=max(c[x[i]][y[i]],ans);
}
}
}
void in(){
scanf("%d",&k);
scanf("%s",ch+1);
for(int i=1;i<=k;i++)x[i]=1000,y[i]=1000;
c[x[1]][y[1]]=1,ans=1;
}
void work(){
int len=strlen(ch+1);
for(int i=1;i<=len;i++){
if(ch[i]=='N')changeN();
if(ch[i]=='E')changeE();
if(ch[i]=='S')changeS();
if(ch[i]=='W')changeW();
}
}
void out(){
if(shu){
sort(x+1,x+k+1);
sort(y+1,y+k+1);
for(int i=1;i<=k;i++)printf("%d ",x[i]-1000);
puts("");
for(int i=1;i<=k;i++)printf("%d ",y[i]-1000);
puts("");
}
else{
printf("%d\n%d\n",x[1]-1000,y[1]-1000);
}
printf("%d\n",ans);
memset(c,0,sizeof(c));
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
memset(ch,0,sizeof(ch));
shu=0;
}
int main(){
cin>>n;
while(n--){
in();
work();
out();
}
return 0;
}
T3
不会,但是据说用两个\(ex\)数论板子
不感兴趣了,虽然这两个板子我曾经会过
T4
\(40pts:\)暴力稳过
又\(20pts:\)暴力不用担心爆空间
又\(10pts:\)暴力不用担心爆时间
\(100pts\):
区间修改,线段树
考虑线段树上区间维护这个东西
如果数不对的话一整个区间直接废掉,我们此时令左标记\(s=-1\)
否则,区间的右标记定为最新值
不合法的情况就是右标记和最新值的差值不为\(1\)

浙公网安备 33010602011771号