2024.11 训练记录

训练记录

11.1

补题,怒学 LCT。

没学会。the end。只会 splay。辅助树太难了。

11.2

无。休息日就摸了一整天鱼,都干了啥我一点也记不清了。

11.3

noip10连

估分 100 + 0 + 20 + 30 = 150

实际 60 + 0 + 20 + 45 = 125

T1 1e5 二分答案 nlog2n 卡完了。咋这样。赛后换了一个快读过了。ok啊我觉得我快读废了。

T2 我写了一个 总长 - LCS长度 疑似没有正确性。没过样例。

T3 写了 n6 的,本来赛时就想到可以前缀和差分优化一下变成 n4 ,但是懒了。想睡觉。

T4 写了 n3 贪心暴力,哦,这么说好像确实可以过 n1000。跑不满吧。这个时候咋又能跑了。

本波老哥封面人物 kenny 女士 HBD!!!!!!ily!

韦达定理

我老是记不住韦达定理

x1+x2=bax1x2=ca

第二个跟离心率一样,说不定这样好记些

11.4

20连D13

估分 20 + 20 + 20 + 35 = 95

实际 20 + 20 + 20 + 35 = 95

"人生已经如此的艰难"场。但是好像质量还不错。

全是最低分暴力,多爽啊。

看似没挂分其实挂分了。

T1 写了 dfs 暴力,只会这个了。我赛时想了一个奇怪的拓扑排序,想想好像是错的,就没再想下去了。

T2 推完式子发现 S(n)=i=1ni2 , 然后写的暴力,其实应该打个表,打完表就能发现,m 是质数的时候,答案是 m12 。痛失 20 分。

T3 暴力。赛时大家样例全过了,就我t了,以为有什么高级做法没想到,结果其实大家分数跟我一样。

T4,暴力 dfs 过了 6个点 我赛时预计暴力除链之外过 5 个点 所以估分是 35,但是过了 6 个点,应该是 40.但是长度为偶数的链忘判了,这个是只输出 1 的,挂了一个点,又变成 35 了。

13:00 :比赛结束的同时 csp 成绩出了。假的。成绩单未上传,请稍后查看! 延迟到 16:00了。

14:25 :成绩等会就出了,我今晚就不能好好睡觉了。

16:00 :成绩单未上传,请稍后查看!延迟至 17:30 提心吊胆。

17:30 :已死。挂了75。爽吧很爽。没有任何感想。能上 jhyz 就好了。bless me. ✋

11.5

20连D14

估分 100 + 0 + 0 + 0 = 100

实际 100 + 0 + 0 + 0 = 100

又是艰难场,本周关键词是 人生已经如此的艰难 吗?

特别难。

不打暴力+罚时吃满 输麻了。我打了 T3 T4 暴力,但是时间复杂度爆了。

T1 一直因为 5 挂了,调了好久才调出来。一个小时才交题。

后面全在打暴力,。

补了 10连T3 和昨天 T1。

看得出来是我 11.6 补的吧、短的要死。

11.6

20连D15

估分 100 + 0 + 30 + 20 = 150

实际 100 + 0 + 0 + 0 = 100

T1 找了半天规律,一开始打表,然后发现我最多只能打到 n=4 的。后面手推+猜。最后算是出来了。因为一开始觉得就是组合数学,就贴了板子,交题的时候ce了。ps:找一下规律可以发现 博导太厉害了 指路:yaotianhao

fi=(i1)×i×fi1+i×(i1)×(i1)×fi2

T2 暴力 n=20 就 G。随手造的数据。(等下 我现在发现疑似刚造的数据不是一棵树啊啊啊???

T3 暴力 dfs 选每个点,并查集看是否连通。不懂为啥挂了。

T4 qn 暴力 常数有可能大点,我写的 multiset ,如果前面有空缺,倒着做一遍看能不能把缺的补上,补好之后再正着做看后面能不能更大;否则就正着做一遍,让后面更大。感觉挺有道理的。(笑点解析:刚知道 rbegin()rend() 都是倒着遍历的)啊啊啊啊啊啊啊清 空 清 小 了 。。爽啊

11.7

20连D16

估分 15 + 0 + 12 + 25 = 52

实际 5 + 0 + 12 + 10 = 27

T1 特殊部分分忘记判 n&1 了,痛失 10 分。

这题太绝了,一直没想出来。写半个题解

题意: 有 n 个数字,a1,a2,,an。每次可以选择两个数字 x,y 删除,然后加入数字 Kxyn1 轮之后只剩下一个数字,问最后剩下的数字最大可能是多少?你要对 q 个不同的 K 进行回答。每组询问独立,都是对于一开始的序列操作。

首先从小到大排序。

考虑一个数操作次数,做奇数次则系数为 +1,做偶数次系数为 -1。单独记很麻烦,所以想到建成一颗树。(好牛的思想

然后一个点往下分裂成两个,突然到一步是为啥,我也忘了。这里挺乱的。

用三元组 {a,b,c} 记录每个树形态,a 表示系数为负的数的个数,b 表示系数为正的数的个数,ck 的系数。

example:2,0,11,2,0 选了其中一个 ai 当前负的,分裂成两个正的数,本来 ai 位置上的数变成 k , k 符号和原先的 ai 一样为负,所以 c1 变成 0 .

给树的形态打表,发现一共 n3 种。发现规律 三元组 a 每次 +3,c 每次 +2 。我也不知道具体咋样,反正别人打表出来是这样

后面就随便来了,根据 n%3==0/1/2 ,分类,答案 a[n]a[x]a[x]+c×k。是个单峰,但是 +2ka[] 是单调的(这是啥)。于是可以二分。然后,然后就做完了。

T2 0感想,期望完全是弱点。

T3 写的暴力。

T4 多写了一部分导致挂了。爽。

11.8

happy school trip day~

远离机房一天!太开心了!

11.9

周六,补了两三题

11.10

noip10连

估分 72 + 8 + 0 + 0 = 80

实际 60 + 0 + 5 + 0 = 65

对不起。我再也不摸鱼了。今天比赛成功把双城之战看了 5 集。200 分钟啊。一场比赛才 270 分钟。我再也不会这样了。

T1经典题 问全0矩阵个数。直接单调栈维护就好,赛时不会写单调栈赢麻了。写的暴力,然后后面有个全部都是0的部分分,直接输出矩阵个数 n(n+1)2×m(m+1)2 就好,您猜怎么着?嘿!少除了一个2 。

T2写的部分分,题目靠 测试点数量 T 来区分测试点,结果我 while(T--)了。导致一分没拿。

T3 输出 -1 骗分,居然有5分,真好啊。

T4没看。

11.11

20连D17

估分 100 + 0 + 0 + 0 = 100

实际 100 + 0 + 0 + 0 = 100

T1 一开始写了一个 40 分暴力。好像睡了一个小时不到,40分钟吧。醒来找规律发现 degp1=3,degpmid1=3,degpmid=2,degpn=2, 剩下的全是 deg=4。找到 deg=23 的,与 deg=2 有边的一定是开头,手模一下就知道了。然后就可以直接从两边往里面扩,判一下行不行。

T2最后几分钟看懂题,但是不会求 border 了。马上加练

T3最后十分钟写了并查集暴力,没过样例,发现好像理解不对,直接放弃。开始吃饭

T4什么忘了,没看题。

少开点会吧,没营养的东西。

11.12

20连D18

估分 100 + 50 + 7 + 0 = 157

实际 100 + 20 + 0 + 0 = 120

T1树状数组写错了,又是这个

void add(int x,int y){
    for(int i=x;i<=n;i+=lowbit(i)){
        c[x]=max(c[x],y);
    }
}

int qry(int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i)){
        res=max(c[x],res);
    }
    return res;
}

经典错误。我真服了。每次都写成 c[x].想了好久lis。之前noip写过一个差不多几乎一样的。

T2 x=6 k=3 的写错了,本来算的时候就觉得有问题,就该再检查一遍。然后 k=1 的后面不知道为啥他妈的 MLE 了。

T3 多判了一个 s[i].l>=l 7分挂没了。喜报:因为出题人数据造错了所以输出 n 能拿18分 早知道我也输出了。

T4 咋这么简单反悔贪心没写出来.

11.13

20连D19

估分 100 + 0 + 19 + 0 = 119

实际 90 + 0 + 0 + 0 = 90

是在丽泽打的。

T1挂了 原因是 a<0 的时候应该 a=(a+mod)%mod 变成正的再算。于是就挂一个点。一开始题读错了。

T2 树上数数做不了一点。

T3 写了 n2q ,但是初始化赋值成 -inf 导致算错了。19 挂了!

是14号补的。很简短。

11.14

20连D20

估分 0 + 0 + 10 + 30 = 40

实际 0 + 0 + 10 + 25 = 35

笑点解析:t1 0300 .

暴力改“正解”改挂了,我就该把暴力拼上去。

T1好简单,想不到,不想说了。我先写了一个纯暴力,再写了一个单调队列优化的假算。后面发现假了,没有心情写了。嘻嘻。

T2 根据题意模拟样例发现不对,搞不懂,不写了。

T3 开场推了点式子,失败。dfs暴力走起。

T4 前6个部分分,dfs暴力 加 n=2 的直接算,但是好像 n=2 挂是因为 取模取少了,或者说出现了负数导致我错了。

最后一场了,完结,送一发鲨鱼火箭炮。。。

11.15

补题。

还补了点普及联考题。(其实也算提高了

11.16

出去玩了,有道题写了一半。

11.17

noip10连 but day11

估分 40 + 100 + 40 + 0 = 180

实际 40 + 90 + 40 + 0 = 170

t1 不是特殊数据的部分插板法式子疑似不太正确。赛后小改一下70.

t2猜了一手,不知道正确性,但是调了调过了。不知道怎么被卡了,改了好久过了,但是不知道是为啥过的,因为改的最后一发以同样方式改第一发,没过。

t3 我还担心 40 的 n4 暴力过不去只能拿 20.但是拿到了,本来会另一个部分分,但是写着写着去摸鱼了,对不起!!!!!!!

t4 看不懂题意,

还我1500啊。

11.18

noip模拟赛

估分 100 + 45 + 8 + 10 = 163

实际 16 + 10 + 8 + 0 = 34

m连估分零头都没。

下楼到学校机房打的,真垃圾啊,这个配置调了一个小时。还不断网。“熟悉比赛环境”。

t1 假算了。大样例都过了 🤡。正解就是贪心的考虑,放入的字符显然肯定在 S 中越靠前越好,那么就需要找再某个位置后面某个字符第一个出现位置。

不到原题在哪 但是补完过了所有数据,没地方放所以我放这里了。

//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;  

#define int long long
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
#define lowbit(x) ((x)&(-x))

#define ppc __builtin_popcount

#define lc(p) ((p)<<1)
#define rc(p) ((p)<<1|1)

#define sqr(x) ((x)*(x))

// #define mod 1000000007
// #define mod 998244353
#define eps 1e-10

#define debug cout<<__LINE__<<" "<<__FUNCTION__<<"\n";
#define spa putchar(' ')
#define ero putchar('\n')

mt19937 rnd(time(0));

constexpr int N=1e6+10,inf=1e18;

inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
inline void write(int x){
	if(!x)putchar('0');
	if(x<0)x=-x,putchar('-');
	int cnt=0,a[30];
	while(x)a[++cnt]=x%10,x/=10;
	while(cnt--)putchar(a[cnt+1]+'0');
}

char s[N],t[N];
int nxt[100010][30];

void solve(){
    scanf("%s",s+1);
    scanf("%s",t+1);
    int ns=strlen(s+1);
    int nt=strlen(t+1);
    for(int i=0;i<=26;i++){
        nxt[ns+1][i]=ns+1;
    }
    for(int i=ns;i;i--){
        for(int j=0;j<=26;j++){
            nxt[i][j]=nxt[i+1][j];
        }
        // memcpy(nxt[i],nxt[i+1],sizeof(nxt[i+1]));
        nxt[i][s[i]-'a'+1]=i;
    }
    int ans=ns;
    int res=0;
    for(int i=1,j=1;i<=ns&&j<=nt;i++){
        if(s[i]>t[j]){
            res++;
            continue;
        }
        if(s[i]<t[j]){
            ans=min(ans,res);
            break;
        }
        for(int k=0;k<t[j]-'a'+1;k++){
            ans=min(ans,res+nxt[i][k]-i-(!k&&j<nt));
        }
        j++;
    }
    write(ans);ero;
}

signed main(){
	freopen("string.in","r",stdin);
	freopen("string.out","w",stdout);
	// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
    int T=read();
    // int T=1;
    while(T--){
        solve();
    }
	return 0;
}

t2 太妙了太妙了

原题链接丢一个

最重要的就是 转换一下 b 序列生成的过程,就相当于 初始有 n 个数,然后 n1 个间隔每次内部进行分裂得到最终序列。这个过程可以用 二叉树森林 描述.

image.png

如图,第一层为初始的数,而下面的若干棵树则代表每个间隔分裂形成的二叉树。上升子序列,就是图中一个不断往右下走的节点序列。

设 dp 状态 fi,j 表示 第 i 个间隔的形成的树的第 j 层最后的答案。特别地记某个树的第零层为对应的间隔的右端点。

转移方程就是 (记 LIS(i,k,j) 表示第 i 个树从 k 层到 j 层的最长上升子序列)

fi,j=maxk=0jfi1,k+LIS(i,k,j)

aiai1 为 2 的幂次的部分分就可以这么做,因为此时树是满的。

不是 2 的幂次时:走到倒数第二层的第一个节点,如果最后一层不满,那么此时这个节点一定没有左儿子最后一层的所有节点都在这个节点右侧,直接走完即可。

还是 dp,就可以做完了。

代码还是丢一个?(贴的理由是这个typora黑色主题配色太诱人了我天呢我想多看看啊哈哈)

//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;  

#define int long long
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
#define lowbit(x) ((x)&(-x))

//#define ppc __builtin_popcount

#define lc(p) ((p)<<1)
#define rc(p) ((p)<<1|1)

#define sqr(x) ((x)*(x))

// #define mod 1000000007
// #define mod 998244353
#define eps 1e-10

//#define debug cout<<__LINE__<<" "<<__FUNCTION__<<"\n";
#define spa putchar(' ')
#define ero putchar('\n')

// mt19937 rnd(time(0));

const int N=1e5+10,inf=1e18;

inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
inline void write(int x){
	if(!x)putchar('0');
	if(x<0)x=-x,putchar('-');
	int cnt=0,a[30];
	while(x)a[++cnt]=x%10,x/=10;
	while(cnt--)putchar(a[cnt+1]+'0');
}

int f[N][70],a[N];

void solve(){
    int n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    for(int i=0;i<=64;i++){
        f[1][i]=1;
    }
    for(int i=2;i<=n;i++){
        int b=a[i]-a[i-1]; // 差
        int s=log2(b); // 层数
        if(!s){
            f[i][0]=f[i-1][0]+1;
        }
        else{
			for(int j=0;j<s;j++){
				f[i][j]=f[i-1][j]+(1ll<<j);
			}
			int res1=b-(1ll<<s); // 本层?
            int res2=1ll<<s-1; // 倒数第二层?
			f[i][s]=max(f[i-1][s]+res1,f[i-1][s-1]+max(res1,res2)+(res1>0));
        }
        for(int j=0;j<=61;j++){
			f[i][j]=max(f[i][j],f[i-1][j]); // 接上一棵树
			if(j){
                f[i][j]=max(f[i][j],f[i][j-1]); // 本树的上一层
            }
		}
    }
    write(f[n][61]);
}

signed main(){
	freopen("lis.in","r",stdin);
	freopen("lis.out","w",stdout);
	// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
    // int T=read();
    int T=1;
    while(T--){
        solve();
    }
	return 0;
}

t3t4先咕着了。有点小懒,两颗线段树不太想写,但我上周题真没补完。

丢个原题链接
(t3)[https://www.luogu.com.cn/problem/P10764] (t4)[https://vjudge.net/problem/Baekjoon-23168]

11.19

记一个 P6175 无向图的最小环问题

很妙,就是用 floyd 求。floyd算法的计算过程中,我们可以取小于 k 的两个节点i,j。若 i,jk 之间均有边,则存在一个可能的最小环 ijk (因为 i,j 之间的路径长度为只经过 1 ~ (k1)号节点的最短路径)。

csp成绩公示后感想在隔壁 出门左转

11.20

noip模拟

估分 100 + 0 + 70 + 20 = 190

实际 100 + 0 + 70 + 20 = 190

t1 cspD7T1原。一模一样。不说了

t2没调出来😠。

考场想法:首先可以想到一个连通块里只要有一个可以清空全场,那这个连通块里所有袋鼠都可以。

题解做法:

维护 (i,j,i,j) 表示考虑位于 (i,j) 的袋鼠最后能否自己存活,并且把位于 (i,j) 的袋鼠移除。对于固定的 (i,j),只要所有的 (i,j,i,j) 都为 true,那么 (i,j) 就可以是赢家。

(i,j,i,j) 可以从 (i±1,j±1,i±1,j±1) 转移而来,可以通过一次 DFS 或 BFS 求出所有的值。

复杂度为 O((nm)2)

没什么难点。

t3 题面式子

i=1nmin(fi,gi)ai

min(fi,gi) 比较难求,考虑到 fi+gimax(fi,gi)=min(fi,gi)

我们就可以把原式子转化为

i=1nfi+gimax(fi,gi)ai

这个就好求了。

t4 考场想法:把 px<py 转换成 xy 一条有向边。不是 dag 则无解。考虑答案就是求一个拓扑序

设在 DAG 上存在一条从 uv 的边数为 k 的路径,若 pu 已知而 pv 未知,则可以推出 pvpu+k;若 pu 未知而 pv 已知,则可以推出 pupvk

首先我们通过上述规则推导出所有位置的取值范围 [Li,Ri]。对于已知未知,显然 Li=Ri=pi;对于未知位置,可以用拓扑排序 + 动态规划来优化。先正向拓扑排序求出 L:对于边 (u,v),做转移 Lv=max(Lv,Lu+1);然后反向拓扑排序求出 R:对于边 (u,v),做转移 Ru=min(Ru,Rv1)

于是转化为如下问题:给定 k 个区间和 k 个互不相同的数,我们需要给每个数匹配一个包含它的区间,此外每个区间匹配的数还要满足一些拓扑关系。如果暂时不考虑拓扑关系的话是一个经典问题,存在一个简单的贪心做法:从小到大枚举所有数,当枚举到 x 时,从所有左端点 x 且还没被匹配的区间中,选择右端点最小的那个匹配给 x,这个过程用优先队列优化。

然后分析一下区间的性质:如果存在边 (u,v),根据转移方程可得 Lu+1LvRu+1Rv,按照上述贪心做法,[Lu,Ru] 一定比 [Lv,Rv] 更早被匹配到,即一定满足 pu<pv。所以直接贪心求出来的就是原问题的合法解,如果贪心无解则原问题一定无解。

原题:

T1 T2 T3: G A M

T4: J

upd:11/21 我今晚全补完了应该。

、#### 11.21

noip模拟

估分 10 + 25 + 40 + 0 = 75

实际 10 + 25 + 0 + 0 = 35

实话说真的就完全摆了,一点都不想写,本来说打两场,突然就多了一场,还要下去打,真的难受,很累,我又不去noip。不过他也不管了,那我也不管。

这次没下发编译器。?????我一整个问号问号问号问号。然后花了一个多小时不到一个半小时下了mingw,太慢太慢了。

无法评价,我一直不知道t1是否可以排序,不知道排序后正确性对不对,

t2直接暴力了,赛后发现简单的一笔。

t3我全 a 的部分分和 只有 2 个 b 的部分分。结果输出输出反了。😠

补了一些题,上数学和英语。zkx 英语不查作业是为啥?那我重写的加一个晚上这一块谁给我补呢?谁给我补呢????有两个没写作业的 ppp 和 xhy 爽了。妈的。

11.22

我做了 cf,还把前几天没有原题的题本地补了,补的没有实感,怪难受的。

11.23

我不知道今天是什么日子(装傻,

出去玩了。

11.24

写英语作业。

11.25

发生了好多事。先不太想说,我不知道怎么表达清楚。

noip模拟赛

估分 0 + 12 + 0 + 10 = 22

实际 0 + 12 + 15 + 0 = 27

t3 输出 n/(xb+xw) 得到15pts。

不评价了,

11.26

摆烂模拟赛。

t1没调出来转暴力,乱得分。30pts

t2 freopen("chess.in","w",stdout) 经典永流传好吗!!!!!我是傻逼。

t3没看。但是几乎是noip10连d7t4原题。亏大啦。

t4没看。但是题面推子+芙莉莲。爱了爱了。芙莉莲天下第一。

记一下t2做法。

牛逼构造。

题意:

(n+2)×(m+2) 的网格 中间 n×m 的网格里每个格子有一个棋子。

一次操作可以选择一个棋子跳过另一个相邻的棋子,方向只有上下左右,并且跳到的位置不能有棋子。操作完跳过的棋子就被移除。

问你最多可以移除多少颗棋子。多测。T106

我不知道这个图是否还会存活,但是我先放这

神秘。

聪明的人可以发现 就是说,连着的三颗棋可以借助下一行/列一颗不位于中间的棋删掉。如下图。

太神秘了。

然后:对于正解,只需考虑 n2 的情况,首先我们要观察出:剩下的最少棋子数要么为 1,要么为 2

根据性质,我们可以证明一个结论:当 m5 时,n×m 的情况下答案等价于 n×(m3) 情况下的答案

利用基本操作以及 n=2 ,可以做到一次删 3 行/列,于是结论成立

那么每次在 n,m 较大的那一维上删 3 个,递归下去,最终一定可以到达 n,m4 的情形,对于这些 n,m4,直接暴搜得到方案即可

我们发现这样构造出的方案能使得最少棋子数不大于 2

不想证明了。

不想写。贴个std。

#include<bits/stdc++.h>
using namespace std ;

typedef long long LL ;
const int N = 1e6+10 ;

int n , m ;
struct nn
{
	int x , y ; char c ;
};
vector<nn> ans[6][6] , p ;
void Remove1( int ax , int ay ) // 消列 
{
	p.push_back({ax,ay+1,'L'}) ;
	p.push_back({ax+2,ay,'U'}) ;
	p.push_back({ax,ay-1,'R'}) ;
}
void Remove2( int ax , int ay ) // 消行 
{
	p.push_back({ax+1,ay+2,'U'}) ;
	p.push_back({ax,ay,'R'}) ;
	p.push_back({ax-1,ay+2,'D'}) ;
}
void work( int ax , int ay , int n , int m )
{
	if( n <= 4 && m <= 4 ) {
		for(nn R : ans[n][m] ) {
			p.push_back({ax+R.x-2,ay+R.y-2,R.c}) ;
		}
		return ;
	}
	if( n > m ) { // 消 3 行 
		int i = 1 ;
		for( i = 1 ; i+3 <= m ; i ++ ) {
			Remove1(ax,ay+i-1) ;
		}
		if( i+2 == m ) {
			Remove2(ax,ay+i-1) ;
			Remove2(ax+1,ay+i-1) ;
			Remove2(ax+2,ay+i-1) ;
		}
		else {
			p.push_back({ax,ay+i,'L'}) ;
			p.push_back({ax+1,ay+i,'L'}) ;
			p.push_back({ax,ay+i-2,'D'}) ;
			Remove2(ax+2,ay+i-2) ;
		}
		work(ax+3,ay,n-3,m) ;
	}
	else { // 消 3 列 
		int i = 1 ;
		for( i = 1 ; i+3 <= n ; i ++ ) {
			Remove2(ax+i-1,ay) ;
		}
		if( i+2 == n ) {
			Remove1(ax+i-1,ay) ;
			Remove1(ax+i-1,ay+1) ;
			Remove1(ax+i-1,ay+2) ;
		}
		else {
			p.push_back({ax,ay,'D'}) ;
			p.push_back({ax,ay+1,'D'}) ;
			p.push_back({ax+2,ay,'R'}) ;
			Remove1(ax,ay+2) ;
		}
		work(ax,ay+3,n,m-3) ;
	}
}
void solve()
{
	scanf("%d%d" , &n , &m ) ;
	p.clear() ;
	if( n == 1 ) {
		for(int j = 2 ; j <= m ; j += 2 ) {
			p.push_back({2,j+1,'L'}) ;
		}
	}
	else if( m == 1 ) {
		for(int i = 2 ; i <= n ; i += 2 ) {
			p.push_back({i+1,2,'U'}) ;
		}
	}
	else work(2,2,n,m) ;
	printf("%d\n" , p.size() ) ;
	for(nn R : p ) {
		printf("%d %d %c\n" , R.x , R.y , R.c) ;
	}
	printf("\n") ;
}

int mp[10][10] , I , J , A ;
int dx[4] = {0,0,1,-1} ;
int dy[4] = {1,-1,0,0} ;
char S[4] = {'R','L','D','U'} ;
vector<nn> ve ;
void dfs( int tot )
{
	if( !ans[I][J].empty() ) return ;
	if( tot==A ) {
		ans[I][J] = ve ;
		return ;
	}
	for(int x = 1 ; x <= I+2 ; x ++ ) {
		for(int y = 1 ; y <= J+2 ; y ++ ) {
			if( mp[x][y] ) {
				for(int k = 0 ; k < 4 ; k ++ ) {
					int tx=x+dx[k] , ty=y+dy[k] , ttx=tx+dx[k] , tty=ty+dy[k] ;
					if( ttx<1||ttx>I+2||tty<1||tty>J+2||!mp[tx][ty]||mp[ttx][tty] ) continue ;
					mp[x][y] = 0 , mp[tx][ty] = 0 , mp[ttx][tty] = 1 ;
					ve.push_back({x,y,S[k]}) ;
					dfs(tot+1) ;
					mp[x][y] = 1 , mp[tx][ty] = 1 , mp[ttx][tty] = 0 ;
					ve.pop_back() ;
				}
			}
		}
	}
}
void pre_work()// 暴搜
{
	for(int i = 2 ; i <= 4 ; i ++ ) {
		for(int j = 2 ; j <= 4 ; j ++ ) {
			int ct[3] = {} ;
			for(int x = 1 ; x <= i+2 ; x ++ ) {
				for(int y = 1 ; y <= j+2 ; y ++ ) {
					if( x==1||x==i+2||y==1||y==j+2 ) mp[x][y] = 0 ;
					else mp[x][y] = 1 , ct[(x+y)%3] ++ ;
				}
			}
			I = i , J = j ;
			if( (ct[0]&1)==(ct[1]&1)&&(ct[1]&1)==(ct[2]&1) ) A = i*j-2 ;//由初始状态直接确定最终答案
			else A = i*j-1 ;
			ve.clear() ;
			dfs(0) ;
		}
	}
}

int main()
{
	pre_work() ;
	int t ;
	scanf("%d" , &t ) ;
	while( t -- ) solve() ;	
	return 0 ;
}

还有一个很悲伤的就是必须去noip了,先说清楚我没抱着打好的想法。

posted @   Slayer-WT!!!!!!!!  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示