P9837 题解
奇怪的构造方法居然过了...
本构造方法暂无证明,只是提供一种乱搞做法。
对于奇数的情况
首先我们从样例入手(为
1 2 3 4 2 5 3 5 1 4 5 4 3 1 2
然后我们对样例进行一点改造:
1 2 3 4 1 5 3 5 2 4 5 4 3 1 2
我们将这个数组水平翻转一下,再顺时针旋转 45 度:
5 3 4 4 5 3 2 1 2 1 1 3 5 4 2
然后就使用瞪眼法,发现偶数行和奇数行规律不同,将它们分离成两部分:
5 4 5 3 1 3 5 4 2
和
3 4 2 1 2 1
我们发现奇数行的最后一行是 1 3 5 4 2
,按照奇偶再分成两部分:1 3 5
和 4 2
。
然后我们发现最后一行先是
然后我们再看倒数第二行 4 5 3
和最后一行去除头尾元素的部分 3 5 4
。
发现倒数第二行只是把最后一行去除头尾元素的部分翻转了。
然后依照该规律向上构造即可。
再看偶行,由下到上就是从小到大的相邻的两个数反复出现而已。
从上到下先是奇数开头,再是偶数开头。
对于偶数的情况
偶数的样例只能自己手搓一个(为
1 2 3 4 1 5 3 6 2 5 5 4 6 1 3 6 5 3 4 2 1
和奇数一样,将这个数组水平翻转一下,再顺时针旋转 45 度:
6 5 5 3 4 3 4 6 6 4 2 1 2 1 2 1 3 5 5 3 1
然后将奇偶行分离:
6 3 4 3 2 1 2 1 2
和
5 5 4 6 6 4 1 3 5 5 3 1
奇数行和另一种情况的偶数行构造一致。
只是从上到下先是偶数开头,再是奇数开头。
不难发现偶数行是对称的。
最后一行的前半部分是 1 3 5
,倒数第二行的前半部分是 4 6
。
然后我们发现最后一行是
两组数据交替出现。
每次向上构造时删除头尾元素即可。
Code
#include<bits/stdc++.h> using namespace std; #define maxn 4003 int mp[maxn][maxn]; int ls[maxn]; int ls1[maxn], ls2[maxn]; void solve1(int n) { for(int i=1;i<=n;i++) ls[i]=(i<=(n>>1)+1)?(i<<1)-1:(n-i+1)<<1; int cnt1=0; for(int i=1;i<=n;i++) { if(i&1) { cnt1++; int mf=cnt1; if(i&2) for(int j=i;j<=n;j++) mp[n-j+i][n-j+1]=ls[mf++]; else for(int j=i;j<=n;j++) mp[j][j-i+1]=ls[mf++]; } else { if(i&2) { int st=i-2; for(int j=i;j<=n;j++) mp[j][j-i+1]=(st^=1)+1; } else { int st=i-1; for(int j=i;j<=n;j++) mp[j][j-i+1]=(st^=1)+1; } } } for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) cout<<mp[i][j]<<' '; cout<<'\n'; } } void solve2(int n) { for(int i=1;i<=n>>1;i++) ls1[i]=(i<<1)-1; for(int i=1;i<=n>>1;i++) ls2[i]=(i<<1); for(int i=(n>>1)+1;i<=n;i++) ls1[i]=((n-i+1)<<1)-1; for(int i=(n>>1)+1;i<=n;i++) ls2[i]=((n-i+1)<<1); int cnt1=0; for(int i=1;i<=n;i++) { if(i&1) { cnt1++; int mf=cnt1; if(i&2) for(int j=i;j<=n;++j) mp[n-j+i][n-j+1]=ls2[mf++]; else for(int j=i;j<=n;++j) mp[j][j-i+1]=ls1[mf++]; } else { if(i&2) { int st=i-2; for(int j=i;j<=n;++j) mp[j][j-i+1]=(st^=1)+1; } else { int st=i-1; for(int j=i;j<=n;++j) mp[j][j-i+1]=(st^=1)+1; } } } for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) cout<<mp[i][j]<<' '; cout<<'\n'; } } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n,w; cin>>n>>w; if(n&1) return solve1(n), 0; else return solve2(n), 0; }
本文作者:redacted-area
本文链接:https://www.cnblogs.com/redacted-area/p/18379517
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步