题解 | #数字方阵#

数字方阵

https://ac.nowcoder.com/acm/problem/15384

来写一篇随机化做法的题解。

尝试只用一次 std::random_shuffle 草过去,发现在一些小数据上确实挺容易爆炸。

那么考虑这么个事情:当 nn 很大的时候,在整个方阵中重复次数一定不会很多,而想让重复次数很多,就必须让 nn 变小(这样碰撞概率才会大)。

所以我们就得到了如下代码:(注:std::random_shuffle 函数用于打乱一个数组的排列)

#include<map>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
int init(){
	char c = getchar();
	int x = 0, f = 1;
	for (; c < '0' || c > '9'; c = getchar())
		if (c == '-') f = -1;
	for (; c >= '0' && c <= '9'; c = getchar())
		x = (x << 1) + (x << 3) + (c ^ 48);
	return x * f;
}
void print(int x){
	if (x < 0) x = -x, putchar('-');
	if (x > 9) print(x / 10);
	putchar(x % 10 + '0');
}
const int N = (int) 1e3 + 5;
int n, p[N * N];
bool check(){
    std::map<int, int>map;
    map.clear();
    for (int i = 1; i <= n; ++i) {
        int s = 0;
        for (int j = 1; j <= n; ++j)
            s += p[(i - 1) * n + j];
        if (map.count(s)) return 0;
        map[s] = 1;
    }
    for (int j = 1; j <= n; ++j) {
        int s = 0;
        for (int i = 1; i <= n; ++i)
            s += p[(i - 1) * n + j];
        if (map.count(s)) return 0;
        map[s] = 1;
    }
    int s = 0;
    for (int i = 1; i <= n; ++i)
        s += p[(i - 1) * n + i];
    if (map.count(s)) return 0;
    map[s] = 1;
    s = 0;
    for (int i = 1; i <= n; ++i)
        s += p[(i - 1) * n + n - i + 1];
    return !map.count(s); // 按照题意检验和
}
int main(){
    srand(time(NULL));
    n = init();
    for (int i = 1; i <= n * n; ++i)
        p[i] = i;
    do{
        std::random_shuffle(p + 1, p + 1 + n * n);
    }while(!check()); // 每做一遍 random_shuffle 就 check 一次,保证输出结果的正确性
    for (int i = 1; i <= n; ++i, putchar('\n'))
        for (int j = 1; j <= n; ++j, putchar(' '))
            print(p[(i - 1) * n + j]);
}
全部评论
欢迎 Hack ~
点赞 回复 分享
发布于 2021-11-17 09:35

相关推荐

2024-12-27 23:45
已编辑
三江学院 Java
程序员牛肉:死局。学历+无实习+项目比较简单一点。基本就代表失业了。 尤其是项目,功能点实在是太假了。而且提问点也很少。第一个项目中的使用jwt和threadlocal也可以作为亮点写出来嘛?第二个项目中的“后端使用restful风格”,“前端采用vue.JS”,“使用redis”也可以作为亮点嘛? 项目实在是太简单了,基本就是1+1=2的水平。而你目标投递的肯定也是小厂,可小厂哪里有什么培养制度,由于成本的问题,人家更希望你来能直接干活,所以你投小厂也很难投。基本就是死局,也不一定非要走后端这条路。可以再学一学后端之后走测试或者前端。 除此之外,不要相信任何付费改简历的。你这份简历没有改的必要了,先沉淀沉淀
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务